WHERE子句中列的顺序是否重要?

big*_*int 33 sql-server performance

WHERE子句中列的顺序是否会影响性能?

例如

假设我把一个具有更高潜力的专栏放在首位,反之亦然?

Ric*_*ard 15

有一个像样的查询优化器:它不应该.

但在实践中,我怀疑它可能.

您只能通过测量来判断您的案例.随着数据库中数据分布的变化,测量结果可能会发生变化.


tva*_*son 12

对于Transact-SQL ,在WHERE子句的条件下,运算符具有已定义的优先级.优化器可能会重新排序此评估,因此您不应依赖短路行为来确保正确性.订单通常是从左到右,但索引的选择性/可用性可能也很重要.简化搜索条件应该可以提高优化器处理它的能力.

例如:

 WHERE (a OR b) AND (b OR c)
Run Code Online (Sandbox Code Playgroud)

可以简化为

 WHERE b OR (a AND c)
Run Code Online (Sandbox Code Playgroud)

显然,在这种情况下,如果可以构造查询以查找b是否先占优势,那么它可能能够跳过a和c的评估,从而运行得更快.优化器是否可以执行这个简单的转换我无法回答(它可能会),但重点是它可能无法进行任意复杂的转换,您可以通过重新排列条件来影响查询性能.如果b更具选择性或具有索引,则优化器可能能够首先使用它构造查询.

编辑:关于基于唯一性的排序问题,我假设您可以根据您的数据(实际的,未假设的)提供给优化器的任何提示都不会受到影响.假装它不会进行任何优化并构建您的查询,就好像您需要将其从大多数选择到最不具有选择性,但是在性能实际上是一个问题之前不要对它进行任何考虑.

引用上面的参考:

逻辑运算符的优先顺序是NOT(最高),后跟AND,后跟OR.括号可用于在搜索条件中覆盖此优先级.逻辑运算符的评估顺序可以根据查询优化器的选择而变化.


Reg*_*ser 8

对于SQL Server 2000/20005/2008,无论您如何在WHERE子句中排列列,查询优化器通常都会给出相同的结果.话虽如此,在编写数以千计的T-SQL命令的过程中,我发现了一些订单改变了性能的极端情况.以下是似乎受此问题影响的查询的一些特征:

  1. 如果查询中有大量表(10个或更多).

  2. 如果在WHERE子句中有多个EXISTS,IN,NOT EXISTS或NOT IN语句

  3. 如果您使用嵌套CTE(公用表表达式)或大量CTE.

  4. 如果FROM子句中有大量子查询.

以下是有关尝试评估快速解决性能问题的最佳方法的一些提示:

  1. 如果问题与1或2有关,则尝试重新排序WHERE子句并比较估计查询计划中查询的子树成本.

  2. 如果问题与3或4有关,那么尝试将子查询和CTE移出查询并让它们加载临时表.如果减少来自T-SQL语句主体的复杂连接和子查询的数量,查询计划优化器在估计查询计划方面更有效.

  3. 如果使用临时表,请确保已为临时表指定了主键.这意味着避免使用SELECT INTO FROM来生成表.相反,在使用INSERT INTO SELECT语句之前,显式创建表并指定主KEY.

  4. 如果您正在使用临时表,并且服务器上的MANY进程也使用临时表,那么您可能希望创建一个在查询过程中被截断并重新加载的更永久的临时表.如果使用TempDB存储工作/临时表,则更有可能遇到磁盘争用问题.

  5. 移动WHERE子句中的语句,将多数数据过滤到WHERE子句的开头.请注意,如果这是您解决问题的方法,那么当查询计划再次混淆生成和选择最佳执行计划时,您的性能可能会再次降低.您最好找到一种方法来降低查询的复杂性,以便WHERE子句的顺序不再相关.

我希望您发现此信息有用.祝好运!