[英]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.