参数嗅探:为什么这会成为一个问题?

Oni*_*ght 7 performance sql-server stored-procedures parameter query-performance

今天,当我从 ASP.NET 网页运行时,我遇到了一个存储过程超时(花费超过 30 秒)的问题,但从 SSMS 运行时执行得很快(花费了 5 秒)。

在怀疑参数嗅探是罪魁祸首后,我屏蔽了输入参数,查询执行得更快。

我的问题是:为什么会发生这种情况?

这个系统已经投入生产超过 5 年了,这是我们第一次在我们的存储过程中看到这样的事情。这是“数据库磨损”吗?

我们已经解决了这个问题,所以这没什么大不了的,但我只是好奇为什么会发生这种情况。

Tho*_*ger 8

基本上发生的事情是,当 SQL Server 看到它需要编译的查询时,它将使用第一次调用的参数来生成执行计划。这可能是也可能不是一件好事,但这就是发生的事情。

例如,假设您有一张水果表(100 行)。有 98 行是 Apple,只有 2 行包含水果 Orange。如果您为 Apple 查询该表,则该计划很可能会使用 Scan 进行编译。这是一件好事,因为它针对 Apple 查询进行了优化。但是当您想查询 Orange 时,该 Scan 效率低下。但正在使用的是存储的计划。

事实是它发生了。它一直在发生。这通常不是一个突出的问题,但在某些情况下,它可能是一个非常大的问题。解决持续的错误参数嗅探问题的方法是,OPTIMIZE FOR在初始编译时生成执行计划时,您可以利用查询提示强制 SQL Server 使用某些参数值。

  • +1 或者,如果计划形状变化很大并且没有您可以有意优化的单个值,则使用“OPTIMIZE FOR UNKNOWN”或“OPTION RECOMPILE”。 (3认同)

Mar*_*ith 6

...但从 SSMS 运行时执行速度很快(需要 5 秒)

相当烦人的是,SSMS 默认是 forSET ARITHABORT ON而大多数客户端库(ADO .Net、ODBC、OLE DB)指定SET ARITHABORT OFF. 可能您有一个“变坏”的计划,但是当您尝试通过 SSMS 进行复制时,ARITHABORT 中的差异导致使用了不同的“好”计划。

应用程序慢,SSMS 快?是一个很好的参考。

为什么会这样?

很可能触发了重新编译,不幸的是,编译使用了一组非典型的输入。