where子句的顺序在SQL中是否重要?

Ziy*_*ang 113 sql performance where-clause

假设我有一个名为PEOPLE3列的表ID, LastName, FirstName,这些列都没有被索引.
LastName更独特,FirstName更不独特.

如果我做2次搜索:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"
Run Code Online (Sandbox Code Playgroud)

我的信念是第二个更快,因为更独特的标准(LastName)在where条款中排在第一位,记录将更有效地消除.我不认为优化器足够聪明,可以优化第一个sql.

我的理解是否正确?

mar*_*c_s 91

不,这个顺序无关紧要(或者至少:无所谓).

任何体面的查询优化器都将查看该子句的所有部分,WHERE并找出满足该查询的最有效方法.

我知道SQL Server查询优化器会选择一个合适的索引 - 无论你有两个条件在哪个顺序.我假设其他RDBMS将有类似的策略.

重要的是你是否有合适的索引!

对于SQL Server,如果您有以下情况,它可能会使用索引:

  • 一个索引 (LastName, FirstName)
  • 一个索引 (FirstName, LastName)
  • just (LastName)或just (FirstName)(或两者)的索引

另一方面 - 再次为SQL Server - 如果您使用从表中SELECT *获取所有列,并且表相当小,那么查询优化器很可能只执行表(或聚簇索引)扫描而不是使用索引(因为查找完整数据页以获取所有其他列的速度非常快).

  • 有趣的注释与SQL服务器,显然谓词中的NOT EXISTS顺序实际上可以影响计划的创建:http://bradsruminations.blogspot.com/2010/04/looking-under-hood.html (2认同)
  • 奇怪的是,对于第一次执行查询,WHERE子句中的条件顺序很重要!我有两个条件,例如:`WHERE T1.col_1/T2.col_2> 10 AND T2.col_2 <> 0`并得到一个'DIVIDE BY 0`错误.在我切换订单后,查询执行的条件成功.然后我把订单换回来,所以我希望再次得到错误,但这次是有效的!最后我的结论是,对于第一次运行,订单确实很重要,直到执行计划建成.之后订单没有没关系,因为优化器/执行计划会处理它 (2认同)
  • 我喜欢你说的,“......或者至少:应该无关紧要”——我完全同意。不幸的是,有时它确实很重要。我见过 SQL 过于复杂以至于优化器无法处理的情况,并且列顺序和表连接顺序等事情确实产生了影响。它取决于 RDBMS、SQL 语句的复杂性,甚至取决于发布。非常复杂的 SQL 会导致错误的优化器决策或在优化器代码中使用硬编码的默认值。 (2认同)

Gor*_*off 18

WHERE子句的顺序不应对符合SQL标准的数据库产生影响.大多数数据库都不保证评估顺序.

不要以为SQL关心订单.以下在SQL Server中生成错误:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0
Run Code Online (Sandbox Code Playgroud)

如果首先执行此子句的第一部分,则只将数字表名称转换为整数.但是,它失败了,提供了一个明确的例子,SQL Server(与其他数据库一样)不关心WHERE语句中子句的顺序.

  • @Jim如果首先评估`ISNUMERIC(table_name)= 1`,那么只会为数字表名调用`CAST`.但由于它未首先进行评估,因此也会对非数字表名称进行"CAST"评估,从而导致出现错误消息. (6认同)
  • 出色的澄清度 (2认同)

03U*_*Usr 9

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3规则评估顺序

...

如果优先级不是由格式或括号确定的,则表达式的有效评估通常从左到右执行.但是,依赖于实现是否实际上是从左到右计算表达式,特别是当操作数或运算符可能导致条件被引发时,或者如果可以在不完全评估表达式的所有部分的情况下确定表达式的结果.

这里复制