MySQL:为什么与变量相比,使用文字条件的查询运行得更快
不确定实际的查询是否重要,但是,我有一个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
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域
存储在存储过程中的一个变量中,并在其他任何地方使用该变量。不要直接在存储过程中使用输入参数。这应该可以做到。