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

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

例如

比如说我把第一个有更高的唯一性的专栏,或者反之亦然?

用一个体面的查询优化器:它不应该。

但实际上,我怀疑它可能。

你只能通过测量来告诉你的情况。 测量结果可能随着数据分布的变化而变化。

对于Transact-SQL,在WHERE子句的条件下 ,运算符有一个定义的优先级。 优化器可能会重新sorting此评估,因此您不应该依赖短路行为来保证正确性。 订单一般从左到右,但是select性/可用性指标可能也很重要。 简化search条件应该会提高优化器处理它的能力。

例如:

WHERE (a OR b) AND (b OR c) 

可以简化为

  WHERE b OR (a AND c) 

很显然,在这种情况下,如果查询可以被构造来查找b是否成立,那么它可能会跳过a和c的评估,从而运行得更快。 优化器是否可以做这个简单的转换,我不能回答(它可能会),但重点是它可能不能做任意复杂的转换,你可能会通过重新排列条件来影响查询性能。 如果b更具select性或具有索引,则优化器可能首先使用它来构build查询。

编辑 :关于基于唯一性sorting的问题,我会假设你可以提供给优化器的任何提示根据你的知识(实际,而不是假设)的数据不会受到伤害。 假设它不会做任何优化,并构build您的查询,就好像您需要从大多数select性到最lessselect性一样定义它,但是在性能实际上是一个问题之前不要执着于此。

引用上面的引用:

逻辑运算符的优先顺序不是(最高),其次是AND,其次是OR。 在search条件中,括号可以用来覆盖这个优先级。 逻辑运算符的评估顺序可以根据查询优化程序的select而变化。

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

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

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

  3. 如果你使用嵌套的CTE(公用表expression式)或大量的CTE。

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

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

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

  2. 如果问题与3或4相关,则尝试将子查询和CTE移出查询,并使其加载临时表。 如果您减lessT-SQL语句正文中的复杂联接和子查询的数量,则查询计划优化器在估计查询计划时的效率会更高。

  3. 如果您正在使用临时表,那么请确定您已经为临时表指定了主键。 这意味着避免使用SELECT INTO FROM来生成表格。 相反,在使用INSERT INTO SELECT语句之前,显式创build表并指定一个主KEY。

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

  5. 移动WHERE子句中的语句,将大部分数据过滤到WHERE子句的开头。 请注意,如果这是您解决问题的办法,那么当查询计划再次产生并select最佳执行计划时,您可能再次performance不佳。 您最好find一种方法来降低查询的复杂性,以便WHERE子句的顺序不再相关。

我希望你find这个信息有帮助。 祝你好运!

这一切都取决于DBMS,查询优化器和规则,但通常它会影响性能。

如果where子句被sorting,使得第一个条件显着地减less了结果集,剩下的条件将只需要对一个较小的集合进行评估。 遵循该逻辑,您可以根据where子句中的条件顺序优化查询。

理论上任何两个相同的查询应该产生相同的查询计划。 由于WHERE子句的顺序对WHERE的逻辑意义没有影响,所以这应该意味着WHERE子句的顺序应该没有任何作用。

这是因为查询优化器的工作原理。 在一个非常简单的概述中:

  1. 首先,SQL Serverparsing查询并构造一个逻辑运算符树(例如JOINSELECT )。
  2. 然后它将这些逻辑运算符转换成“物理操作树”(例如“嵌套循环”或“索引扫描”,即执行计划)
  3. 接下来,通过交换等价的操作,估计每个计划的成本,直到find最优的计划,通过一组等价的“物理操作树”(即执行计划)进行置换。

第二步完成是一个完全的方法 – 它只是select第一个/最明显的物理树,但是在第三步查询优化器能够查看所有等价的物理树(即执行计划),等等只要这些查询实际上是相同的,那么我们在步骤2中得到的初始计划并不重要,所有计划在步骤3中要考虑的一组计划是相同的。

(我不记得逻辑/物理树的真实名称,它们在一本书中,但不幸的是,这本书是我现在的世界的另一面)

请参阅以下一系列博客文章以获取更多详细信息内部优化器:构build计划 – 第1部分

但实际上查询优化器经常没有机会在步骤3中考虑所有等价树(对于复杂查询,可能有大量可能的计划),因此在一定的截止时间之后,步骤3被缩短,查询优化器必须select迄今为止发现的最佳计划 – 在这种情况下,并不是所有的计划都会被考虑。

有很多幕后的魔法继续保证查询优化器有select地和有意识地select计划来考虑,所以计划select的大部分时间是“足够好” – 即使它不是绝对最快的计划,其速度可能并不比理论上的最快,

这意味着如果我们在步骤2中有不同的起始计划(如果我们以不同的方式编写我们的查询,可能会发生这种情况),这可能意味着在步骤3中考虑了不同的计划子集,因此理论上 SQL Server可以根据写入的方式,为等价查询提出不同的查询计划。

实际上,99%的时间你不会注意到这个差别(对于许多简单的计划,不存在任何差别,因为优化器将实际考虑所有的计划)。 你也不能预测这些是如何工作的,所以看起来合理的东西(比如把WHERE子句放在一个特定的顺序中)可能没有任何预期的效果。

绝大多数情况下,查询优化器将确定select所请求数据的最有效方式,而不pipeWHERE子句中定义的SARGS的顺序如何。

sorting由诸如相关列的select性(SQL Server根据统计信息知道)以及是否可以使用索引等因素确定。

如果你是ANDing条件,第一个不是真的会返回false,所以order会影响性能。