首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用子查询时,MySQL "IN“查询非常慢,但使用显式值时,查询速度很快

使用子查询时,MySQL "IN“查询非常慢,但使用显式值时,查询速度很快
EN

Stack Overflow用户
提问于 2011-02-16 23:23:29
回答 4查看 24.6K关注 0票数 29

我有一个MySQL查询(UBU10.04,Innodb,核心i7,16 Ubu内存,固态硬盘,MySQL参数优化):

代码语言:javascript
复制
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秒才能完成。但是,如果我替换子查询的结果并执行以下操作:

代码语言:javascript
复制
SELECT
COUNT(DISTINCT subscriberid)
FROM
em_link_data
WHERE
linkid in (24899,24900,24901,24902);

那么查询将在不到1毫秒的时间内运行。仅子查询的运行时间就不到1ms,对列linkid进行了索引。

如果我将查询重写为连接,也不会超过1ms。为什么" in“查询使用子查询会如此慢,为什么使用值查询会如此快?我不能重写查询(购买的软件),所以我希望有一些调整或提示,以加速这个查询!任何帮助都是非常感谢的。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-16 23:27:10

子查询在你每次计算它们的时候都会执行(无论如何都是在MySQL中,而不是所有的RDBMSes中),也就是说你基本上是在运行700万个查询!如果可能的话,使用连接可以将其减少到1。即使添加索引提高了它们的性能,您仍然可以运行它们。

票数 26
EN

Stack Overflow用户

发布于 2011-02-16 23:25:01

是的,使用子查询的IN速度很慢。请改用联接。

代码语言:javascript
复制
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.linkidem_link.id上定义了索引。

票数 6
EN

Stack Overflow用户

发布于 2011-02-16 23:45:49

问题是,MySQL从外到内执行查询,而您可能认为您的子查询只执行了一次,然后将其结果传递给外部查询的WHERE表达式(参见MySQL documentation)。

如果你不能重写你的查询,你应该做以下优化:

  • campaignidlink上添加索引,因为FrustratedWithFormsDesigner说
  • 通过执行EXPLAIN SELECT ...
  • enable和调整查询缓存来检查子查询是否正确地使用了索引,因为这应该会加快子查询被

多次调用的速度

另一个想法是安装MySQL proxy并编写一个小脚本来拦截您的查询,然后重写它以使用连接。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5018284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档