我有一个MySQL查询(UBU10.04,Innodb,核心i7,16 Ubu内存,固态硬盘,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进行了索引。
如果我将查询重写为连接,也不会超过1ms。为什么" in“查询使用子查询会如此慢,为什么使用值查询会如此快?我不能重写查询(购买的软件),所以我希望有一些调整或提示,以加速这个查询!任何帮助都是非常感谢的。
发布于 2011-02-16 23:27:10
子查询在你每次计算它们的时候都会执行(无论如何都是在MySQL中,而不是所有的RDBMSes中),也就是说你基本上是在运行700万个查询!如果可能的话,使用连接可以将其减少到1。即使添加索引提高了它们的性能,您仍然可以运行它们。
发布于 2011-02-16 23:25:01
是的,使用子查询的IN
速度很慢。请改用联接。
SELECT
COUNT(DISTINCT subscriberid)
FROM em_link_data JOIN em_link ON em_link_data.linkid=em_link.id
WHERE em_link.campaignid = '2900' AND em_link.link != 'open'
并确保您已经在em_link_data.linkid
和em_link.id
上定义了索引。
发布于 2011-02-16 23:45:49
问题是,MySQL从外到内执行查询,而您可能认为您的子查询只执行了一次,然后将其结果传递给外部查询的WHERE表达式(参见MySQL documentation)。
如果你不能重写你的查询,你应该做以下优化:
campaignid
和link
上添加索引,因为FrustratedWithFormsDesigner说EXPLAIN SELECT ...
多次调用的速度
另一个想法是安装MySQL proxy并编写一个小脚本来拦截您的查询,然后重写它以使用连接。
https://stackoverflow.com/questions/5018284
复制相似问题