存储过程性能随机下降;琐碎的ALTER修复它。为什么?

时间:2009-12-04 22:49:52

标签: .net sql-server performance stored-procedures

我在SQL Server 2005上有几个存储过程,我注意到从我在四个服务器的IIS6 Web场中运行的ASP.NET MVC应用程序调用时,会突然花费很长时间才能完成。正常,预期执行时间不到一秒;意外的异常执行时间为25-45秒。这个问题似乎永远无法纠正。

但是,如果我更改了存储过程(即使我没有更改过程中的任何内容,除非可能为SSMS Modify命令创建的脚本添加空格),完成时间将恢复为预期的完成时间。 / p>

IIS和SQL Server在单独的盒子上运行,两者都运行Windows Server 2003 R2 Enterprise Edition。 SQL Server是标准版。所有机器都配备双Xeon E5450 3GHz CPU和4GB RAM。使用TCP / IP协议通过千兆以太网访问SQL Server(不确定是什么物理介质)。

Web场中的所有Web服务器都存在此问题。当我从开发机器上的SSMS中的查询窗口调用该过程时,该过程在正常时间完成。这很奇怪,因为我认为SSMS使用与.NET中相同的SqlClient驱动程序。当我将Web应用程序的开发实例指向生产数据库时,我再次得到异常长的完成时间。如果我的SqlCommand Timeout太短,我得

  

System.Data.SqlClient.SqlException:   超时已过期。超时期限   在完成之前已经过去了   操作或服务器不是   响应。

问题:为什么在存储过程中执行ALTER而不实际更改其中的任何内容,将完成时间恢复到不到一秒,如预期的那样?

编辑:为了澄清,当应用程序运行缓慢时,它会在SSMS中使用相同的参数同时运行良好。我能辨别的唯一区别是登录凭证(下次我注意到行为时,我将使用相同的信用卡从SSMS检查)。最终目标是使过程以预期的速度持续运行,而不需要偶尔进行干预。

解决方案:我想更新此问题以防其他人遇到此问题。根据以下答案的引导,我能够始终如一地重现这种行为。为了测试,我利用sp_recompile并将其中一个敏感的sprocs传递给它。然后,我从我的浏览器发起一个网站请求,该请求将使用非典型参数调用sproc。最后,我向一个调用带有典型参数的sproc的页面发起一个网站请求,并观察由于sproc调用上的SQL超时而导致请求没有完成。

要在SQL Server 2005上解决此问题,我已向OPTIMIZE FOR添加了SELECT提示。易受攻击的sprocs都具有this article中描述的“一体化”模式。这种模式当然不是理想的,但考虑到项目的时间表,这是必要的权衡。

3 个答案:

答案 0 :(得分:7)

参数嗅探和计划重用。你时不时会得到一个糟糕的计划。执行ALTER会破坏过程中的元数据版本,以便在下次执行时重新编译计划。解决方案取决于一系列因素,你可能有不好的SQL,你可能会得到一个不吉利的'优化',我们无法知道。在缓慢的时候识别过程中的语句。 SQL事件探查器是您的朋友,跟踪SP:StmtCompleted eevnt,持续时间>例如5000。

答案 1 :(得分:5)

可能会重新执行执行计划。

有多种方法可以强制重新生成它,以及避免参数嗅探的方法,其中执行计划是根据参数确定的,但可能不适合所有输入。如果你是在2008年,我建议使用OPTIMIZE FOR UNKNOWN选项。

或者,使用局部变量屏蔽所有输入变量以避免参数嗅探,并考虑调用WITH RECOMPILE或以这种方式声明SP。

另外,请确保您的统计信息是最新的。过时的统计数据可能意味着计划不再适用。

Remus的回答中的评论也表明了一些可能影响服务器选择的计划的事情。

答案 2 :(得分:2)

当您说SSMS中的查询运行正常时,请考虑以下事项:

  1. 查询计划基于查询字符串的确切字节数字结构进行缓存,包括空格
  2. 带参数的查询计划可能与具有固定值的查询(#1的推论)不同
  3. 您可以尝试使用SQL事件探查器,并将整个慢速查询从那里复制并粘贴到SSMS中,看看它是否仍然很慢。