假设列pkey
是mysql表T
的主键。基于解释输出:为什么mysql不优化这个简单的查询
此查询需要扫描每个只有1行两种推导PRIMARY选择(正如人们所期望的那样):
SELECT * FROM (SELECT * FROM T where pkey=10) t;
但此查询需要为执行完整的线性扫描 DERIVED和PRIMARY选择(这表示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优化是关于如何执行尽可能快的查询,而不是如何将错误查询重写为更好的查询。 – Amadan
MySQL不会将外部查询的谓词向下推入视图查询中。为什么? MySQL优化器中没有执行该操作的代码路径。它不会发生,因为没有代码可以做到这一点。正如Gordon的答案很好地解释的,MySQL对该陈述所做的是MySQL正是如此。 (这种行为的好处之一就是我们从MySQL优化器中获得了非常可预测的执行计划。) – spencer7593
@Amadan: 问题是关于*为什么*它没有优化它,而不是为什么两个线性第二种情况下需要扫描(这很明显,一旦知道它不会优化它)。请参阅Gordon的答案。 而你正在用你轻浮的陈述来打击整个优化领域:“如果它太微不足道了,人类可以做到,也许人类有理由不这样做”。除非你可以告诉每个mysql规格的两个查询是如何不同的(就任何可观察到的效果而言),否则你不能排除优化的可能性。 – abi