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 语句?的主要内容,如果未能解决你的问题,请参考以下文章

C# 是不是使用 await 对 if 语句执行短路评估?

SQL Server 查询表值参数的短路 EXISTS 语句

SQL Server查询表值参数的短路EXISTS语句

SQL中多分支If语句的性能(Sql Server 2008)

在这种特定情况下,SQL Server 会始终短路吗?

SQL Server UPDATE语句的用法详解