SQL Server 是不是会短路 IF 语句?
Posted
技术标签:
【中文标题】SQL Server 是不是会短路 IF 语句?【英文标题】:Does SQL Server short-circuit IF statements?SQL Server 是否会短路 IF 语句? 【发布时间】:2015-02-13 00:37:47 【问题描述】:我正在优化一些频繁使用的存储过程,并遇到了一个我找不到任何答案的场景:在存储过程中评估 TSQL 时,SQL Server 是否会短路 IF
声明?
例如,假设一个存储过程的代码类似于:
IF @condition1 = 1
OR EXISTS(SELECT 1 FROM table1 WHERE column1 = @value1)
...
在这种情况下,SQL Server 是否会短路评估,以便在前面的子句评估为 true 时永远不会执行 EXISTS
语句?
如果它从来没有或只是有时会这样做,那么我们需要进行一些重写。
【问题讨论】:
不保证。检查执行计划,看看你的情况是否如此。 谢谢,“不保证”是我想要的。问题是这些存储过程是在数百个客户数据库上执行的,所以如果执行计划确定了这一点,我们不能假设它会在每个客户的系统上进行相同的评估并需要重写。 如果你想要一个铸铁保证,那么分离成多个if
语句就可以了。当I looked at this before 我发现它的一些例子不是短路。您还可以考虑使用 case 语句。
@MartinSmith:这是很好的信息,我非常喜欢案例陈述方法。
这个问题似乎是在询问是否在查询之外发生短路。我看到的所有答案和链接都与查询案例有关。我猜想在这种特殊情况下确实会发生短路并且是有保证的,但我不知道。有没有人可以解决在查询之外的语句中是否发生短路的问题(即它不在 Where 子句之类的东西中)?
【参考方案1】:
即使它看起来有效,也不应该依赖它。 CASE 语句是文档中唯一声明为短路的东西,但即使这样也不是(或至少不是)始终是这种情况(嘻嘻)。这是一个 bug,幸运的是,它在 SQL Server 2012 中得到了修复(请参阅 cmets)。
除了@Martin 就该问题发表的评论中的 cmets 链接的兔子洞(肯定是一个有趣的)之外,您还应该查看这篇文章:
Understanding T-SQL Expression Short-Circuiting
以及与该文章相关的论坛。
【讨论】:
【参考方案2】:好消息是它似乎短路了。这是一个最小的例子:
DECLARE @condition1 bit = 1
IF (@condition1 = 1) OR EXISTS(SELECT 1 FROM sys.objects)
PRINT 'True'
ELSE
PRINT 'False'
当@condition
设置为1时,这是执行计划:从sys.objects
扫描0行
当@condition
设置为0 时,它扫描sys.objects
表:
但不能保证每次都是这样。
【讨论】:
以上是关于SQL Server 是不是会短路 IF 语句?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 查询表值参数的短路 EXISTS 语句