【发布时间】:2011-06-28 10:40:56
【问题描述】:
我有一个 MySQL 查询(Ubu 10.04、Innodb、Core i7、16Gb RAM、SSD 驱动器、MySQL 参数优化):
SELECT
COUNT(DISTINCT subscriberid)
FROM
em_link_data
WHERE
linkid in (SELECT l.id FROM em_link l WHERE l.campaignid = '2900' AND l.link != 'open')
表 em_link_data 大约有 700 万行,em_link 有几千行。 完成此查询大约需要 18 秒。但是,如果我替换结果 子查询并执行以下操作:
SELECT
COUNT(DISTINCT subscriberid)
FROM
em_link_data
WHERE
linkid in (24899,24900,24901,24902);
那么查询将在不到 1 毫秒的时间内运行。子查询单独运行不到1ms,列linkid被索引。
如果我将查询重写为连接,也少于 1 毫秒。为什么带有子查询的“IN”查询如此之慢,为什么其中的值如此之快?我无法重写查询(购买的软件),所以我希望有一些调整或提示来加速这个查询!任何帮助表示赞赏。
【问题讨论】:
-
你的解释计划是怎么说的?你配置了哪些索引?
-
我猜
em_link需要一个包含campaignid和link的索引。 -
这是优化器的结果: select count(distinct
ackci.em_link_data.subscriberid) ASCOUNT(DISTINCT subscriberid)fromackci.em_link_datawhere( ackci.em_link_data.linkid,( ( ( ackci.em_link_data.linkid) 在 em_link 中 PRIMARY where ((ackci.l.@987654304 @ = '2900') 和 (ackci.l.link'打开') 和 ((ackci.em_link_data.linkid) =ackci.@987654348 @.id))))) -
我相信 MySQL 5.6.7 使用
materialization选项解决了这个问题。如果子查询独立于外部查询,那么它会被执行一次,在内部变成临时表,然后加入外部查询。这一直是 MySQL 的一个非常令人沮丧的问题,Oracle 在几十年前设法解决了这个问题。