SQL Server 2008R2中"SET STATISTICS TIME ON"的奇怪副作用?

Ser*_*rge 6 sql-server sql-server-2008-r2

SET STATISTICS TIME OFF;

DECLARE @String AS VARCHAR(10), @I INT = 1    

WHILE @I <= 3
BEGIN
SET @String = CASE @I WHEN 1 THEN 'First' WHEN 2 THEN 'Second' WHEN 3 THEN 'Third' END;

    SELECT  @String AS [StatsTimeOff] OPTION(RECOMPILE)

    SET STATISTICS TIME ON

    SELECT @String AS [StatsTimeOn]  OPTION(RECOMPILE)

    SET STATISTICS TIME OFF

SET @I +=1;
END
Run Code Online (Sandbox Code Playgroud)

返回

StatsTimeOff
------------
First

StatsTimeOn
-----------
First


StatsTimeOff
------------
Second

StatsTimeOn
-----------
First


StatsTimeOff
------------
Third

StatsTimeOn
-----------
First
Run Code Online (Sandbox Code Playgroud)

为什么组合OPTION(RECOMPILE)SET STATISTICS TIME ON显然使变量回归到其初始值?

我以前从未见过SET STATISTICS TIME ON对结果产生影响.
我错过了什么吗,在这里?

小智 1

这似乎确实是一个错误,并且我可以在 SQL 2008 R2 SP2 中重现该错误。我相信你的案例陈述有点偏离它,因为你可以通过简单地选择@I来重现该问题,我将重写它如下:

DECLARE @I INT = 1   

WHILE @I <= 3
BEGIN
    SELECT FirstRun = @I OPTION(RECOMPILE)

    SET STATISTICS TIME ON

    SELECT SecondRun = @I OPTION(RECOMPILE) 

    SELECT ThirdRun = @I OPTION(RECOMPILE)

    SET @I +=1
END
Run Code Online (Sandbox Code Playgroud)

因为我相信这是一个错误,所以我不会尝试修复它。不过,我建议将所有 SSMS 设置移至批处理的开头,并以这种方式运行。此解决方法可以避免该问题。

我的猜测是,当选项更改时,它会返回整个查询以尝试找出如何制定执行计划,并且当它这样做时,它会(错误地)获取变量的初始值。由于它使用 OPTION(RECOMPILE) 该参数作为常量放入计划中,这就是为什么您仅在使用该选项时看到此错误。

非常奇怪的是,如果您在此之后立即再次运行该 select 语句,它就会开始返回正确的值。这是我没想到的,它为您提供了另一种解决方法,允许您打开统计信息并在其之后运行其他操作,例如,奇怪的是,SET STATISTICS IO ON。