级联查询速度急剧下降,但它们独立工作正常
Posted
技术标签:
【中文标题】级联查询速度急剧下降,但它们独立工作正常【英文标题】:cascaded query slows down drastically, but they work fine independently 【发布时间】:2012-03-07 16:40:39 【问题描述】:查询 1:
select distinct email from mybigtable where account_id=345
耗时 0.1 秒
查询2:
Select count(*) as total from mybigtable where account_id=123 and email IN (<include all from above result>)
耗时 0.2 秒
查询 3:
Select count(*) as total from mybigtable where account_id=123 and email IN (select distinct email from mybigtable where account_id=345)
需要 22 分钟,其中 90% 处于“准备”状态。为什么这需要这么多时间。
表是 innodb,在 mysql 5.0 上有 320 万行
【问题讨论】:
【参考方案1】:还有更多:
我怀疑您的查询缓存已针对查询 1 和 2 进行了预热,从而导致结果出现偏差。在FLUSH QUERY CACHE;
之后重试
我怀疑查询 3 将通过一个临时表,最有可能在磁盘上,而查询 2 保证从 RAM 运行。 my.cnf 中临时表的默认设置非常保守。
试试这个以确保您不会受到 MySQL 中旧的去优化错误的影响
.
SELECT count(DISTINCT b.primary_key_column) AS total
FROM mybigtable a
INNER JOIN mybigtable b
ON a.email=b.email
WHERE a.account_id=345
AND b.account_id=123
【讨论】:
我也怀疑过,我冲了一遍又试了一遍,结果还是一样。您指的是哪些特定变量? 我的 max_heap_table_size = 67M tmp_table_size = 67M .. 你认为我应该改变吗? 我们讨论了多少个电子邮件地址(中间结果) 仅 128 个。同样奇怪的是,查询上的解释显示了出色的计划,并且状态一直显示“准备中”。有没有办法可以更详细地看到它,比如 mysql 的 strace ?探查器没有帮助,因为它显示了相同的“准备”状态 之前也尝试过加入.. 它需要很长时间,直到 30 分钟才完成,我不得不杀死它:(【参考方案2】:MySQL 不擅长 IN 子句中的子查询。我将其重写为:
SELECT COUNT(*) as total
FROM mybigtable t
INNER JOIN (
SELECT DISTINCT email
FROM mybigtable
WHERE account_id = 345
) x
ON t.email = x.email
WHERE t.account_id=123
【讨论】:
【参考方案3】:经过深思熟虑并在 dba.se 的帮助下,这是最有效的最终查询。
select count(*) EmailCount from
(
select tbl123.email from
(select email from mybigtable where account_id=123) tbl123
LEFT JOIN
(select distinct email from mybigtable where account_id=345) tbl345
using (email)
WHERE tbl345.email IS NULL
) A;
【讨论】:
以上是关于级联查询速度急剧下降,但它们独立工作正常的主要内容,如果未能解决你的问题,请参考以下文章