在Sql Server 2005中,当我有多个参数时,我是否可以保证评估顺序始终从左到右?
使用示例:
select a from table where c=1 and d=2
在此查询中,如果“c = 1”条件失败,将永远不会评估“d = 2”条件?
PS-“c”是整数索引列,d是需要全表扫描的大型varchar和非索引列
更新我试图避免执行两个查询或条件语句,我只需要这样的事情:如果“c condition”失败,就有办法避免执行沉重的“d条件”,因为它是在我的情况下不需要。
答案 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的确定性短路评估 言。
它确实比下面的网站中解释的要复杂一些:
答案 6 :(得分:1)
MS SQL Server查询优化器会发生短路,是的。保证。
运行:
select 1 where 1 = 0 and 1 / 0 = 10
即使你将零除以零,它也会正常运行而不是错误,因为查询优化器会短路评估where子句。这对任何where子句都有影响,其中你是“和”-ing,其中一个和部分是常量。