繁体   English   中英

我该如何优化这个MySQL查询?

[英]How can I optimize this MySQL query?

有人可以解释为什么子查询添加组使得此查询需要这么长时间(30秒):

SELECT *
FROM aggregate_songlist AS a
INNER JOIN musical_works AS m 
ON a.musical_work_id = m.id
WHERE m.genre='rock' AND m.id NOT IN 
(SELECT sources.musical_work_id FROM sources GROUP BY sources.musical_work_id HAVING COUNT(sources.musical_work_id) > 8)

如果我删除'group by'(并增加子查询的结果),则需要0.07秒:

SELECT *
FROM aggregate_songlist AS a
INNER JOIN musical_works AS m 
ON a.musical_work_id = m.id
WHERE m.genre='rock' AND m.id NOT IN 
(SELECT sources.musical_work_id FROM sources)

子查询中没有外部引用,因此它只应执行一次,对吧? 自己执行:

SELECT sources.musical_work_id FROM sources GROUP BY sources.musical_work_id HAVING COUNT(sources.musical_work_id) > 8

只需0.01秒。

有什么解释吗? 有关如何改变它的任何建议?

子查询中没有外部引用,因此它只应执行一次,对吧?

你会这么认为,但不是。 如果查看EXPLAIN,您将看到子查询被称为“依赖子查询”而不是“子查询”。 这意味着每次都会重新执行。 这是MySQL 5.0中的一个已知错误 ,并在MySQL 6.0中修复。

要解决此问题,您可以使用其他方法之一来检查另一个表中是否存在行。 三种常用方法是NOT IN,NOT EXISTS和LEFT JOIN ... WHERE ... IS NULL,所以你仍然有两个选项。

NOT IN可能是你的问题。 尝试加入它(你必须翻转HAVING子句):

SELECT *
FROM aggregate_songlist AS a
INNER JOIN musical_works AS m 
ON a.musical_work_id = m.id
LEFT JOIN (
      SELECT sources.musical_work_id FROM sources 
      GROUP BY sources.musical_work_id   
      HAVING COUNT(sources.musical_work_id) <= 8) AS t
ON m.id = t.musical_work_id
WHERE m.genre='rock' AND t IS NULL

[更新以反映@Mark Byers评论,谢谢!]

SELECT *
FROM 
aggregate_songlist AS a
INNER JOIN musical_works AS m 
ON a.musical_work_id = m.id
LEFT JOIN (
      SELECT sources.musical_work_id FROM sources 
      GROUP BY sources.musical_work_id   
      HAVING COUNT(sources.musical_work_id) <= 8)
AS t
ON m.id = t.musical_work_id
WHERE
m.genre='rock' AND
t.musical_work_id IS NULL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM