是MS-SQL AND / OR条件(执行短路评估)?

时间:2017-09-09 20:33:18

标签: sql-server stored-procedures

我正在创建一个存储过程(简化)

create procedure sp_mysp @p1 bit AS
if (@p1 = 1 AND EXISTS(select  * from mytable1))
BEGIN....END
ELSE IF (@p = 0 AMD EXISTS(select * from mytable2))
BEGIN....END

所以问题是,SQL总是会检查mytable1中的数据,还是只检查mytable1中的数据,如果@ p1等于1

(类似&& in c#)

2 个答案:

答案 0 :(得分:6)

无法保证此行为。

expr1 AND expr2发生 的短路评估示例

SET STATISTICS IO ON

IF EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)  
AND EXISTS (SELECT COUNT(*) FROM master..spt_values HAVING COUNT(*)=1)
PRINT 'Y'

EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)false(意味着And - ed表达式必须为False),但IO结果显示仍然评估了第二个条件。

Table 'spt_values'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'spt_monitor'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server 可以执行此操作。我在测试中看到了这一点

SET STATISTICS IO ON

DECLARE @p1 BIT = NULL

IF ( @p1 = 1
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '1'

ELSE IF ( @p1 = 0
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '2'

输出

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

从未访问过显示spt_values

这是通过执行计划中的传递谓词条件实现的。有一些关于here的信息。

  

如果passthru谓词的计算结果为true,则join返回该行   ....如果passthru   谓词评估为false,连接正常进行

enter image description here

答案 1 :(得分:2)

短路is not guaranteed in SQL Server TSQL

数据库尝试优化查询,并且可以以与查询中观察到的顺序不同的顺序执行表达式/操作。您可以查看a blog entry from Microsoft,一组 experiments in SQL Server 2005以及OR behavior in SQL server上的另一个讨论。