SQL Server程序执行计划的奇怪问题

时间:2011-07-26 11:40:07

标签: sql-server sql-server-2005 stored-procedures sql-execution-plan

我想知道你们是否可以帮我解决我最近在SQL Server上遇到的一个奇怪问题。

我有一个存储过程(让我们调用SPold)这是一个相当大的存储过程(在应用程序中不可能这样做,因为大约6000个用户的信息需要单独返回(我根据Surname将其减少到1000))。存储过程通常在几秒钟内执行,并且每隔几分钟调用一次。

今天早上,存储过程突然执行了4-10倍,导致了一些超时。我发现通过使用新名称(SPnew)复制程序并执行,我会再次获得快速执行时间。这向我表明执行计划是原始的SPold的问题,所以我决定通过重新编译来执行它。这会更快地返回结果(尽管不如SPnew快),但用户对SPold的后续调用再次变慢。这就好像没有保留新的计划。

我所做的就是解决此问题,将Exec SPnew放入SPold,现在对SPold的调用再次快速返回。

有谁知道这里发生了什么?隔夜更新的唯一事情是统计数据,但我认为这会影响SPoldSPnew

2 个答案:

答案 0 :(得分:5)

由于参数嗅探,听起来您遇到了错误缓存的查询计划。

你可以发布存储过程吗?

在SQL Server 2005中,您可以使用OPTIMIZE FOR查询提示来获取参数的首选值,以解决与参数嗅探相关的一些问题:

  

OPTIMIZE FOR 指示查询优化器为本地使用特定值   编译和优化查询时的变量。使用该值   仅在查询优化期间,而不是在查询执行期间。   OPTIMIZE FOR可以抵消参数检测行为   优化程序或可在创建计划指南时使用。更多   信息,请参阅Recompiling Stored ProceduresOptimizing Queries in Deployed Applications by Using Plan Guides

虽然SQL Server 2005不支持OPTIMIZE FOR UNKNOWN(在SQL Server 2008中引入) 将消除给定参数的参数嗅探:

OPTION (OPTIMIZE FOR (@myParam UNKNOWN))

通过将参数复制到局部变量,然后在查询中使用局部变量,可以在SQL Server 2005中实现相同的效果。

答案 1 :(得分:4)

我也遇到过Sql Server 2005的两个“奇怪”案例,这也可能与你的问题有关。

在第一种情况下,我的程序在以dbo运行时快速执行,并且在从应用程序运行时在另一个用户帐户下运行缓慢。

在第二种情况下,程序的查询计划针对首次调用过程的参数值进行了优化,然后该计划也被重用于其他参数值,导致执行缓慢。

对于第二种情况,解决方案是将参数值复制到过程中的局部变量中,然后使用查询中的变量而不是参数。