在查询之前更改存储过程中的参数值是否会影响基数估计?

ada*_*101 3 sql-server stored-procedures parameter-sniffing

在像这样运行查询之前,我经常在顶部“清理”我的存储过程的参数:

-- Scrub params
SET @SearchText = NULLIF(@SearchText, '')
SET @ThreadId = NULLIF(@ThreadId, 0)
SET @Hashtag = NULLIF(@Hashtag, '')
Run Code Online (Sandbox Code Playgroud)

但后来从这篇文章中我读到了以下内容:

如果查询谓词使用局部变量,请考虑重写查询以使用参数而不是局部变量。当查询优化器创建查询执行计划时,局部变量的值是未知的。当查询使用参数时,查询优化器使用传递给存储过程的第一个实际参数值的基数估计。

如果值源自参数,是否算作使用局部变量?我想知道我的参数清理是否会影响查询执行计划的创建。

Pau*_*ite 6

如果值源自参数,是否算作使用局部变量?

不,SQL Server 仍会将引用视为参数,它可能会被嗅探

“参数嗅探”是指 SQL Server 的执行环境在编译或重新编译期间“嗅探”当前参数值并将其传递给查询优化器以便它们可用于生成可能更快的查询执行计划的过程。“当前”一词是指导致编译或重新编译的语句调用中存在的参数值。在 SQL Server 2000 和 SQL Server 2005 中,在编译或重新编译以下类型的批处理期间会嗅探参数值:

  • 存储过程
  • 通过 sp_executesql 提交的查询
  • 准备好的查询

通常,整个过程的计划是在执行开始之前编译(并嗅探参数),因此SET在嗅探发生时您将不会执行。如果在过程开始执行后由于任何原因重新编译语句,则可能会发生异常。在这种情况下,重新编译过程将看到您设置的新值。

在大多数情况下,每个引用参数的语句都将根据嗅探的值进行优化,而不是您在过程中所做的任何更改。

进一步阅读:参数嗅探、嵌入和重新编译选项