为什么mysql不优化这个简单的查询

为什么mysql不优化这个简单的查询,mysql,sql,database,query-optimization,Mysql,Sql,Database,Query Optimization,假设列pkey是mysql表T的主键。根据解释输出: 此查询只需扫描派生和主select的每一行,正如预期的那样: 从中选择*从中选择*从T中选择,其中pkey=10 T 但此查询需要对派生和主选择进行完整的线性扫描这表明MySQL根本无法优化查询: 从T中选择*从T中选择*,其中pkey=10 查询2至少有两种可能的优化:可以将其转换为1,或者完全删除子查询,即将其更改为SELECT*FROM T,其中pkey=10,以及其他可能的优化 MySQL无法优化查询是否有更深层次的原因,即优化是否可

假设列pkey是mysql表T的主键。根据解释输出:

此查询只需扫描派生和主select的每一行,正如预期的那样:

从中选择*从中选择*从T中选择,其中pkey=10 T

但此查询需要对派生和主选择进行完整的线性扫描这表明MySQL根本无法优化查询:

从T中选择*从T中选择*,其中pkey=10

查询2至少有两种可能的优化:可以将其转换为1,或者完全删除子查询,即将其更改为SELECT*FROM T,其中pkey=10,以及其他可能的优化

MySQL无法优化查询是否有更深层次的原因,即优化是否可能会改变查询的可观察行为,在这种情况下,MySQL不优化查询是正确的


PS:我正在运行MySQL版本5.6.13。

MySQL实现子查询。因此,当您编写此命令时,将修复子查询的别名:

SELECT *
FROM (SELECT * FROM T) t
WHERE pkey = 10;
您正在告诉SQL引擎将T复制到中间临时表中。此表没有索引,因此此查询比第一个版本昂贵得多


这是MySQL的一个特性。几乎任何其他数据库都能正确处理此问题。我认为即使是MS Access也是如此。

在一般情况下,外部表不是内部表,并且没有内部表的索引。我对MySQL开发人员没有深入的了解,但是如果它是如此微不足道,以至于连一个人都能做到,那么这个人可能有理由不去做,而且不应该去碰它。DBMS优化是关于如何尽可能快地执行查询,而不是如何将错误查询重写为更好的查询。MySQL不会将谓词从外部查询下推到视图查询中。为什么?MySQL优化器中没有执行该操作的代码路径。它不会发生,因为没有代码来执行它。正如Gordon的回答很好地解释的那样,MySQL对该语句所做的就是MySQL对它所做的。这种行为的好处之一是,我们可以从MySQL优化器中获得相当可预测的执行计划。@Amadan:问题是为什么它不优化它,而不是为什么在第二种情况下需要两次线性扫描,这是显而易见的,一旦你知道它不会优化它。见下面戈登的答案。你正在用你的轻浮的陈述击落整个优化领域,如果它是如此微不足道,以至于人类可以做到,也许人类有理由不这样做。除非你能说出这两个查询在每个mysql规范中在任何可观察的效果方面是如何不同的,否则你不能排除优化的可能性。我相信我在第一句话中所说的Gordon和spencer7583在mysql优化的可预测性方面所说的几乎是一样的。我想说的是,你应该感谢@spencer7583,因为他给了你更多的技术解释。如果你看上面的评论,我确实感谢了。在MySQL术语中,别名为t的内联视图被称为派生表。当我们了解MySQL是如何处理这个问题时,他们使用的名称就有意义了。内联视图查询的结果将具体化为一个表。完成该步骤后,可以对新填充的表运行外部查询。我们在存储视图中也观察到了同样的行为。MySQL不像大多数其他RDBMS那样,将谓词从外部查询向下推送到视图查询中。