选择“where子句”评估顺序

时间:2009-01-27 16:38:33

标签: sql sql-server sql-server-2005 performance select

在Sql Server 2005中,当我有多个参数时,我是否可以保证评估顺序始终从左到右?

使用示例:

  

select a from table where c=1 and d=2

在此查询中,如果“c = 1”条件失败,将永远不会评估“d = 2”条件?

PS-“c”是整数索引列,d是需要全表扫描的大型varchar和非索引列

更新我试图避免执行两个查询或条件语句,我只需要这样的事情:如果“c condition”失败,就有办法避免执行沉重的“d条件”,因为它是在我的情况下不需要。

7 个答案:

答案 0 :(得分:29)

评估订单无法保证。优化器将尝试使用可用信息找到执行查询的最有效方法。

在您的情况下,由于c是索引而d不是,因此优化器应查看索引以查找与c上的谓词匹配的所有行,然后从表数据中检索这些行以评估d上的谓词。

但是,如果它确定c上的索引不是非常有选择性(虽然不是在你的例子中,性别列很少被有效索引),它仍然可以决定进行表扫描。

要确定执行顺序,您应该获得查询的解释计划。但是,要意识到该计划可能会根据优化程序认为现在最好的查询而改变。

答案 1 :(得分:4)

SQL Server将为其执行的每个语句生成优化计划。您无需订购where子句即可获得该优惠。你唯一拥有的是它会按顺序运行语句:

SELECT A FROM B WHERE C
SELECT D FROM E WHERE F

将在第二行之前运行第一行。

答案 2 :(得分:2)

您可以查看查询的执行计划并确定它实际上要执行的操作。我认为SQL Server的查询引擎应该进行这种类型的扫描,并将智能地将其转换为操作。就像,如果你做“昂贵的操作和错误”,它会很快评估为假。

根据我所学到的,你输入的内容(和可能的内容)与实际执行的内容不同。您只是告诉服务器您期望的结果类型。如何得到答案并不会将您提供的代码从左到右关联起来。

答案 3 :(得分:2)

如果您想确定可以查看Query Execution Plan。 MSSQL构建/优化的执行计划足够智能,可以在varchar列之前检查索引列。

答案 4 :(得分:2)

当我们引用的条件仅包括文字或常量时,就完成了短路。例如,假设我们有一个TableA表,其列号为1到10的所有正数,然后我写这个查询。

从TableA WHERE TableA.num<中选择num 0和1/0 = 10。

会导致错误。

编译器是否足够聪明以确定我的第二个子句是否由常量组成,因此它应该在求值子句之前评估它,这需要从表或索引进行任何扫描?

答案 5 :(得分:1)

控制评估顺序的一种方法是使用CASE表达式。

[编辑]

我试图表达的流行观点是:

  

您不能依赖表达式评估顺序   “WHERE OR”,因为优化器可能会选择一个计划   在第一个谓词之前评估第二个谓词。但   CASE声明中表达式的评估顺序是固定的,   所以你可以依赖于CASE的确定性短路评估   言。

它确实比下面的网站中解释的要复杂一些:

http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not-even-with-case.aspx

答案 6 :(得分:1)

MS SQL Server查询优化器会发生短路,是的。保证。

运行:

select 1 where 1 = 0 and 1 / 0 = 10

即使你将零除以零,它也会正常运行而不是错误,因为查询优化器会短路评估where子句。这对任何where子句都有影响,其中你是“和”-ing,其中一个和部分是常量。

相关问题