在 T-SQL 中使用 IF 会削弱或破坏执行计划缓存吗?

Ant*_*nes 20 performance sql-server-2005 sql-server-2008 sql-server query-performance

有人向我建议,在 t-SQL 批处理中使用 IF 语句对性能有害。我试图找到一些确认或验证这个断言。我使用的是 SQL Server 2005 和 2008。

断言是以下批次:-

IF @parameter = 0
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END
Run Code Online (Sandbox Code Playgroud)

SQL Server 无法重用生成的执行计划,因为下一次执行可能需要不同的分支。这意味着 SQL Server 将从执行计划中完全删除一个分支,因为它已经可以确定当前执行需要哪个分支。这是真的吗?

此外,在这种情况下会发生什么:-

IF EXISTS (SELECT ....)
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END
Run Code Online (Sandbox Code Playgroud)

无法提前确定将执行哪个分支?

Mar*_*inC 10

SQL Server 通过忽略存储过程中的条件分支来优化存储过程的查询计划的编译过程。计划将根据第一次执行时使用的参数生成,如果分支的参数不同,这将导致问题。

我会将每个分支的 SQL 放入它们自己的存储过程中,以便生成的计划基于该分支参数的实际使用情况。


gbn*_*gbn 6

唯一的捷径是 IF 1 = 1

@parameter 和 EXISTS 仍然需要处理“一般情况”(@parameter = 42比如)

话说……实际的执行计划以及捕获重新编译事件的分析器是什么意思?(我不喜欢按照 Jao 的回答估计的计划)


小智 3

尝试显示估计的执行计划,而不是实际的。您会看到第一个包含COND运算符。

该运算符也包含在缓存的执行计划中。在您的示例中,估计的执行计划将包含 1 个 COND 运算符和 2 个 SELECT 分支,因此将完全可重用。因为在执行批处理时,SQL Server 不仅评估 DML 语句,还评估所有其他语句,从计划中获取它们。

执行计划内部是一个类似于表达式树的结构。