【发布时间】:2015-05-08 00:44:55
【问题描述】:
假设列 pkey 是 mysql 表 T 的主键。基于 EXPLAIN 输出:
-
对于 DERIVED 和 PRIMARY 选择,此查询只需要扫描 1 行(正如人们所期望的那样):
SELECT * FROM (SELECT * FROM T where pkey=10) t; -
但是这个查询需要对两个 DERIVED 和 PRIMARY select 做一个完整的线性扫描(这表明 MySQL 根本无法优化查询):
SELECT * FROM (SELECT * FROM T) t where pkey=10;
查询 #2 至少有两种可能的优化:可以将其转换为 #1,或者完全删除子查询(即将其更改为 SELECT * FROM T where pkey=10),以及可能的其他优化。
MySQL 无法优化查询是否有更深层次的原因,即优化是否有可能会改变查询的可观察行为(在这种情况下,MySQL 通过不优化来做正确的事情)?
PS:我正在运行 MySQL 版本 5.6.13。
【问题讨论】:
-
一般情况下,外表不是内表,也没有内表的索引。我对 MySQL 开发人员没有洞察力,但如果它是如此微不足道,甚至人类也可以做到,那么人类可能有理由不这样做,也不应该碰它。 DBMS 优化是关于如何尽可能快地执行查询,而不是关于如何将错误的查询重写为更好的查询。
-
MySQL 不会将外部查询中的谓词下推到视图查询中。为什么? MySQL 优化器中没有执行该操作的代码路径。它不会发生,因为没有代码可以做到这一点。正如 Gordon 的回答很好地解释的那样,MySQL 对该语句的作用正是 MySQL 对它的作用。 (这种行为的一个好处是我们可以从 MySQL 优化器中获得非常可预测的执行计划。)
-
@Amadan:问题是关于 为什么 它不优化它,而不是为什么在第二种情况下需要两次线性扫描(这很明显,一旦你知道它不会优化它)。请参阅下面戈登的回答。而且你用你的轻率陈述否定了整个优化领域“如果它是如此微不足道以至于人类可以做到,也许人类有理由不这样做”。除非您可以根据 mysql 规范(就任何可观察的效果而言)判断这两个查询有何不同,否则您不能排除优化的可能性。
-
我相信我在第一句话中陈述了 Gordon 所做的几乎相同的事情,以及 spencer7583 关于 MySQL 优化的可预测性所做的相同事情。我宁愿说你应该感谢@spencer7583,因为他给了你更多的技术解释。
-
如果你看你上面的评论,我看到了。
标签: mysql sql database query-optimization