Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:为什么与变量相比,使用文字条件的查询运行得更快_Mysql_Variables_Stored Procedures - Fatal编程技术网

MySQL:为什么与变量相比,使用文字条件的查询运行得更快

MySQL:为什么与变量相比,使用文字条件的查询运行得更快,mysql,variables,stored-procedures,Mysql,Variables,Stored Procedures,不确定实际的查询是否重要,但是,我有一个MySQL存储过程,其中我注释掉了除以下查询之外的其他部分 INSERT INTO temp_attribution (`attribute_type`, `domain`, `id`, `name`, `score`, `rank`, `partner_match`, `person_match`, `sponsor_match`, `date_match`) SELECT 'Campaign' AS attribute_type, domain, id

不确定实际的查询是否重要,但是,我有一个MySQL存储过程,其中我注释掉了除以下查询之外的其他部分

INSERT INTO temp_attribution (`attribute_type`, `domain`, `id`, `name`, `score`, `rank`, `partner_match`, `person_match`, `sponsor_match`, `date_match`)
SELECT 'Campaign' AS attribute_type, domain, id, name, score, (@proc_counter := @proc_counter + 1) AS rank,
    partner_match, person_match, sponsor_match, date_match
FROM (
    SELECT m_c.domain, m_c.campaign_id AS id, m_c.name, m_c.client_id, m_c.sent_date,
        proc_sponsors AS invoice_sponsor, bs.sponsor AS campaign_sponsor, 
        proc_email AS invoice_email, aes_decrypt(m_r.email, in_encrypt_key) as campaign_email,
        if (m_c.client_id = proc_client_id COLLATE latin1_general_ci, 'Yes', 'No') AS partner_match,
        if (aes_encrypt(proc_email, in_encrypt_key) = m_r.email, 'Exact Email', 'Email Domain') AS person_match,
        if (LOCATE(CONVERT(bs.sponsor USING utf8mb4), proc_sponsors) > 0, 'Sponsor',
            if (CONVERT(bs.vendor USING utf8mb4) = proc_vendor, 'Vendor', 'No') )  AS sponsor_match,
        if (datediff(proc_invoice_date, m_c.sent_date) BETWEEN 0 AND 92, 'Within Three', 'Within Six') AS date_match,
        (
            if (m_c.client_id = proc_client_id COLLATE latin1_general_ci, 45, 10) + 30 +
            if (LOCATE(CONVERT(bs.sponsor USING utf8mb4), proc_sponsors) > 0, 10,
                if (CONVERT(bs.vendor USING utf8mb4) = proc_vendor, 5, 0) ) +
            if (datediff(proc_invoice_date, m_c.sent_date) BETWEEN 0 AND 92, 15, 5)
        ) AS score 
    FROM campaign_table m_c
    INNER JOIN recipient_table m_r ON m_c.domain = m_r.domain AND m_c.campaign_id = m_r.campaign_id
    LEFT JOIN booking_sponsor bs ON m_c.domain = bs.domain AND m_c.campaign_id = bs.campaign_id
    WHERE datediff(proc_invoice_date, m_c.sent_date) BETWEEN 0 AND 185
    AND ( aes_encrypt(proc_email, in_encrypt_key) = m_r.email OR m_r.email_domain = proc_email_domain )
) T ORDER BY score DESC, sent_date DESC LIMIT 5;
以“proc_u”开头的字段实际上是在过程开始时声明的变量,初始化只需0.385秒,而整个过程需要15秒

在一个单独的查询窗口中,我复制了相关的查询,并替换了以“proc_è”开头的变量,以测试速度和优化,如下所示

INSERT INTO temp_attribution (`attribute_type`, `domain`, `id`, `name`, `score`, `rank`, `partner_match`, `person_match`, `sponsor_match`, `date_match`)
SELECT 'Campaign' AS attribute_type, domain, id, name, score, (@proc_counter := @proc_counter + 1) AS rank,
    partner_match, person_match, sponsor_match, date_match
FROM (
    SELECT m_c.domain, m_c.campaign_id AS id, m_c.name, m_c.client_id, m_c.sent_date,
        'VENDOR SPONSOR VALUE' AS invoice_sponsor, bs.sponsor AS campaign_sponsor, 
        'johnsmith@domain.com' AS invoice_email, aes_encrypt('johnsmith@domain.com', 'secret_key') as campaign_email,
        if (m_c.client_id = m_c.client_id COLLATE latin1_general_ci, 'Yes', 'No') AS partner_match,
        if (aes_encrypt('johnsmith@domain.com', 'secret_key'), 'Exact Email', 'Email Domain') AS person_match,
        if (LOCATE(CONVERT(bs.sponsor USING utf8mb4), 'VENDOR SPONSOR VALUE') > 0, 'Sponsor',
            if (CONVERT(bs.vendor USING utf8mb4) = 'VENDOR', 'Vendor', 'No') )  AS sponsor_match,
        if (datediff('2016-10-14', m_c.sent_date) BETWEEN 0 AND 92, 'Within Three', 'Within Six') AS date_match,
        (
            if (m_c.client_id = m_c.client_id COLLATE latin1_general_ci, 45, 10) + 30 +
            if (LOCATE(CONVERT(bs.sponsor USING utf8mb4), 'VENDOR SPONSOR VALUE') > 0, 10,
                if (CONVERT(bs.vendor USING utf8mb4) = 'VENDOR', 5, 0) ) +
            if (datediff('2016-10-14', m_c.sent_date) BETWEEN 0 AND 92, 15, 5)
        ) AS score
    FROM campaign_table m_c
    INNER JOIN recipient_table m_r ON m_c.domain = m_r.domain AND m_c.campaign_id = m_r.campaign_id
    LEFT JOIN booking_sponsor bs ON m_c.domain = bs.domain AND m_c.campaign_id = bs.campaign_id
    WHERE datediff('2016-10-14', m_c.sent_date) BETWEEN 0 AND 185
    AND ( aes_encrypt('johnsmith@domain.com', 'secret_key') = m_r.email OR m_r.email_domain = 'domain.com' )
) T ORDER BY score DESC, sent_date DESC LIMIT 5;

现在,神奇的是,在不做任何其他事情的情况下,查询将在两秒钟内运行。这怎么可能呢?

想出来了。一些声明的变量类型与所比较的列不同,因此我猜MySQL无法以最有效的方式进行比较。

proc_uu是存储过程的输入参数吗?如果是我,我想我应该尽量把问题减少到造成明显瓶颈所必需的最小程度。@PrabhatG示例:DECLARE proc_email_domain VARCHAR(255)CHARSET utf8mb4;设置proc_email_domain=(SOME QUERY)@草莓即使我只接受最内部的查询并在一个proc中运行它,而不进行任何特殊计算,它在proc中的运行速度也要慢得多。示例:在m_c.domain=m_r.domain和m_c.campaign=m_r.campaign\u id=m_r.campaign\u id左加入预订m_c.domain=bs.domain和m_c.campaign\u id=bs.campaign\u id中选择1,其中datediff('2016-10-14',m_c.sent\u date)介于0和185之间(aes\u encrypt('johnsmith@domain.com','secret_key')=m_r.email或m_r.email_domain='domain.com')@ShahidThaika:我不太确定,但这似乎是一个
参数嗅探问题。您可以了解它。基本上,将
proc\u email\u域
存储在存储过程中的一个变量中,并在其他任何地方使用该变量。不要直接在存储过程中使用输入参数。这应该可以做到。