查询优化 - WHERE子句中表达式的顺序

时间:2014-01-15 19:35:37

标签: mysql sql performance optimization

假设我有一个名为numbers的表:

userID  ColA  ColB
------------------
25      10     11
25      10     16
28      10     11
28      10     16
29      12     14  
29      10     16

我想查找具有userID 28和colA = 10以及colB = 16

的所有行

我的问题是查询结构。如果我首先查找userID,然后查找colA和colB值,例如

select * from numbers where userID=28 AND (colA=10 AND colB=16)

这比首先寻找值更快,例如

select * from numbers where (colA=10 AND colB=16) AND userID=28

或者真的没什么区别吗?我想我正在询问引擎如何读取查询结果,因为(colA = 10 AND colB = 16)的结果比userID = 28更多。因此,我会先假设最少的可能吗?

我也了解索引等。

2 个答案:

答案 0 :(得分:3)

您的RDBMS将找出该查询的最佳执行计划。您将无法更改这些子句的顺序以提高性能,因为RDBMS在制定计划时已经考虑过这样的事情。

您可以使用EXPLAIN命令查看有关RDBMS决定使用的实际执行计划的更多信息。

答案 1 :(得分:1)

你的整个问题没有意义:

  

我的问题是查询结构。如果我首先查找userID,和   然后是colA和colB值,例如

缺少索引或分区,数据库只是逐行扫描表。它查找一行中的值,并在“同时”对行进行所有比较。有可能 - 但绝不保证 - 表达的顺序将是评估的顺序。这将深入MySQL代码的内部,并可能从版本更改为版本。 SQL绝对不指定评估的顺序。我知道MySQL明确没有在select子句中指定评估顺序。但我不知道where

如果我们假设短切,评估的顺序可能会对性能产生微观影响。也就是说,首先进行比较。如果它是假的,则不再进行比较。我不知道MySQL做了快捷方式。即使它确实如此,对where子句的性能影响也是微不足道的,并进行了三次简单的比较。与将数据加载到页表中相比,评估条件的时间无关紧要。

索引的情况变得有点复杂。理论上,您可以在每个列上有一个单独的索引,MySQL需要选择要使用的索引(如果有)。在这种情况下,查询引擎将查看统计信息以估计每个条件的选择性。它不会使用您的评估顺序。