**结束。**此问题需要详细的调试信息。它目前不接受答案。
**想改进这个问题吗?**更新问题,使其成为堆栈溢出的主题。
两年前关门了。
改进这个问题
一位程序员同事向我展示了他创建的一个查询,如下所示:
SELECT a.row, b.row, c.row
FROM
a LEFT JOIN
b ON (a.id = b.id) LEFT JOIN
c ON (c.otherid= b.otherid)
WHERE a.id NOT IN (SELECT DISTINCT b.id bb
INNER JOIN
c cc ON (bb.a_id = cc.a_id)
WHERE (bb.date BETWEEN '2018-08-04 00:00:00' AND '2018-08-06 23:59:59'))
GROUP BY a.id ORDER BY c.otherid DESC;
因此,我通过删除第二个查询并直接应用where子句来缩短它:
SELECT a.row, b.row, c.row
FROM
a LEFT JOIN
b ON (a.id = b.id) LEFT JOIN
c ON (c.otherid= b.otherid)
WHERE b.date NOT BETWEEN '2018-08-04 00:00:00' AND '2018-08-06 23:59:59'
GROUP BY a.id ORDER BY c.otherid DESC;
在此之前,一切似乎都很好,两个查询返回相同的结果集。问题是,第二个查询的执行时间是第一个查询的三倍。这怎么可能?谢谢
1条答案
按热度按时间v9tzhpje1#
这些查询有很大的不同(我们假设失踪者
FROM
在第一个版本中,子查询中的关键字是将其放入问题的结果,并且原始查询没有相同的语法错误。此外,参考b.id
在SELECT
子查询的列表非常可疑,我们怀疑它实际上是对bb.id
... 但我们只是猜测。)如果两个查询返回相同的精确结果集,则这是数据中的一种情况(我们可以演示两个查询结果不同的数据集。)
“缩短”查询并不一定会优化它。
真正重要的(就绩效而言)是执行计划。也就是说,正在执行哪些操作,以什么顺序执行,对于大型表,哪些索引可用,哪些索引正在使用。
没有表和索引定义,就不可能给出明确的诊断。
建议:使用mysql
EXPLAIN
查看每个查询的执行计划。假设原始查询具有
WHERE
格式条款:(假设我们保证子查询返回的值永远不会为null…)
可以重写为
NOT EXISTS
关联子查询以获得等效结果:或者可以重写为反连接
对于大型集合,需要有适当的索引才能获得最佳性能。
问题中的重写不能保证返回相同的结果。