Mil*_*rdo 4 sql-server stored-procedures sql-server-2005 sql-execution-plan
我想知道你们是否可以帮我解决我最近在SQL Server上遇到的一个奇怪问题.
我有一个存储过程(让我们调用SPold
)相当大,有很多计算(不能在应用程序中执行此操作,因为大约6000个用户的信息需要一次性返回(我将此值减少到1000)姓)).存储过程通常在几秒钟内执行,并且每隔几分钟调用一次.
现在今天早上,存储过程突然执行了4-10倍,导致了一些超时.我发现通过使用新名称(SPnew
)执行该过程的副本并执行,我将再次获得快速执行时间.这告诉我执行计划是原始的问题SPold
,所以我决定通过重新编译来执行它.这样可以更快地返回结果(虽然没有那么快SPnew
),但用户的后续调用SPold
再次变慢.这就好像没有保留新计划.
我所做的就是解决这个问题放Exec SPnew
成SPold
,现在调用SPold
正在迅速再次返回.
有谁知道这里发生了什么?那一夜更新的唯一的事就是统计数据,但我认为这应该不会影响这两个SPold
和SPnew
.
听起来您因为参数嗅探而遇到错误缓存的查询计划.
你可以发布存储过程吗?
在SQL Server 2005中,您可以使用OPTIMIZE FOR查询提示来获取参数的首选值,以解决与参数嗅探相关的一些问题:
OPTIMIZE FOR指示查询优化器在编译和优化查询时使用特定值作为局部变量.该值仅在查询优化期间使用,而不是在查询执行期间使用.OPTIMIZE FOR可以抵消优化程序的参数检测行为,也可以在创建计划指南时使用.有关更多信息,请参阅使用计划指南重新编译存储过程和优化已部署应用程序中的查询.
虽然SQL Server 2005不支持OPTIMIZE FOR UNKNOWN(在SQL Server 2008中引入),它将消除给定参数的参数嗅探:
OPTION (OPTIMIZE FOR (@myParam UNKNOWN))
Run Code Online (Sandbox Code Playgroud)
通过将参数复制到局部变量,然后在查询中使用局部变量,可以在SQL Server 2005中实现相同的效果.