我们有以下表达式作为T-Sql查询:
Exp1 OR Exp2
Exp1为True时是否评估Exp2?我认为没有必要对它进行评估。
类似地;为,
Exp1 AND Exp2
是Exp2评估吗?
答案 0 :(得分:6)
与某些编程语言不同,您在T-SQL WHERE
子句中的cannot count上short-circuiting。 It might happen, or it might not
答案 1 :(得分:2)
SQL Server不一定按从左到右的顺序计算表达式。评估订单由执行计划控制,并且基于整个查询的总体估计成本来选择计划。因此,不确定SQL是否会执行您所描述的那种短路优化。这种灵活性使得opimiser变得有用。例如,可能是每种情况下的第二个表达式可以比第一个表达式更有效地进行评估(例如,如果它被索引或受到某些约束)。
SQL也使用三值逻辑,这意味着双值逻辑中使用的某些等价规则不适用(尽管这不会改变您描述的具体示例)。
答案 2 :(得分:0)
SQL Server有时会执行布尔短路,有时则不会。
这取决于生成的查询执行计划。选择的执行计划取决于几个因素,包括WHERE子句中列的选择性,表大小,可用索引等。
答案 3 :(得分:0)
SQL Server查询运算符OR和AND是可交换的。没有固有的顺序,查询优化器可以自由选择开始评估的最低成本路径。一旦设定了计划,如果结果是预先确定的,则不评估其他部分。
此知识允许查询
select * from master..spt_values
where (type = 'P' or 1=@param1)
and (1=@param2 or number < 1000)
option (recompile)
当@param设置为1时,保证评估模式短路。此模式是可选滤波器的典型模式。请注意,@params是否在其他部分之前或之后进行测试无关紧要。
如果您非常擅长SQL并且知道查询最好强制执行某个计划,则可以使用CASE语句对SQL Server进行游戏,CASE语句始终以嵌套顺序进行评估。以下示例将强制type='P'
首先评估始终。
select *
from master..spt_values
where
case when type='P' then
case when number < 100 then 1
end end = 1
如果您不相信上次查询的评估顺序,请尝试此
select *
from master..spt_values
where
case when type='P' then
case when number < 0 then
case when 1/0=1 then 1
end end end = 1
尽管表达式1/0=1
中的常量是评估的最低成本,但它永远不会被评估 - 否则查询将导致除以零而不返回任何行(没有行master..spt_values匹配两个条件)。