变量嗅探?

jes*_*esi 5 performance sql-server sql-server-2014 query-performance performance-tuning

这可能是愚蠢的,感觉就像我要回去尝试理解基础知识。

所以我创建了一个如下所示的测试表并在其上创建一个聚集索引

create table test( c1 int)

DECLARE @Random INT;
DECLARE @Upper INT;
DECLARE @Lower INT
SET @Lower = 1 
SET @Upper = 10000 
while 1=1
begin
SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
insert into test SELECT @Random
end 

create clustered index cidx on test(c1)
Run Code Online (Sandbox Code Playgroud)

现在我使用实际执行计划运行以下查询

DECLARE @Min INT

SET @Min = 216 --selected this cause this was a histogram step

select * from test  where c1 = @Min
select * from test  where c1 = @Min option(recompile)
Run Code Online (Sandbox Code Playgroud)

因此,对于第一个查询,行为符合预期,估计行数是根据密度向量计算的。

搜索谓词 - 搜索关键字1:前缀:[db].[dbo].[test].c1 = 标量运算符([@Min]

在此处输入图片说明

但是对于第二个查询,看起来 sql server 可以使用选项(重新编译)嗅探值。我认为即使我们使用选项重新编译,SQL Server 也无法嗅探变量?

搜索谓词 - 搜索关键字1:前缀:[DB].[dbo].[test].c1 = 标量运算符((216)

在此处输入图片说明

因此,正如您从估计的行数中看到的,第一个是 3.2511,它来自密度向量,而对于第二个,估计的 7 行数来自直方图。

那么当我们重新编译即席查询时,SQL Server 可以嗅探变量是真的还是我不明白的东西?

Dan*_*man 3

此行为是查询提示主题中的文档:

编译查询计划时,RECOMPILE 查询提示使用查询中任何局部变量的当前值,如果查询位于存储过程内,则使用传递给任何参数的当前值。