运行存储过程的随机超时 - 删除重新创建修复程序

时间:2011-06-26 23:11:41

标签: sql database timeout database-administration

所以我在一个10岁的系统上使用一个带有.net 3.5 web前端的大型数据库(30 gig)sql 2005。它有新旧位

我们遇到的问题越来越频繁。

存储过程(到目前为止我们有4个不同的)决定它会超时。呼叫从Web服务器发生并达到30秒超时并记录到我们的错误日志。该网站使用单一登录(我知道这是错误的,但由于遗留代码,它无法更改)。

在此之后,我运行完全相同的呼叫,它需要(以我身份登录)1秒。

问题仍然存在于这一个存储过程中,直到我们删除并重新创建它,获得大量超时。每个sp调用都有不同的参数。 在获取与当前用户相关的所有无符号关闭班次时,所以将当前用户作为参数传入

解决方案有效,但我不明白为什么。

我们的发布周期为两周,此错误发生在此期间的任何时间。它发布在发布后一周发布后的第二天,最后一天发布后12天。

在每个版本中删除我们SQL多脚本所有存储过的procs / triggers / functions / views,每次删除并重新创建。

所有我能想到的是存储过程执行计划已损坏/出错并且重新创建它会清除它。

我正在考虑调用sps WITH RECOMPILE选项,这是不是没有? <或p>可接受的方式

3 个答案:

答案 0 :(得分:3)

这听起来非常像我一次又一次看到的问题 - 存储过程计划已从计划缓存中刷新,并且下次运行该过程时,传入的参数会导致一个计划可能对这组参数很有用,但对其他组合表现非常好。

如果您有'可选'参数 - 其中NULL 可以传递一个值,并且您在OR子句中使用WHERE来应对那么这通常会导致这种情况。

WITH RECOMPILE可能会导致很多CPU每次都要编译计划 - 如果存储过程被大量调用,那么这很容易对服务器的整体性能产生影响 - 无论这个os是否超过了效果一个糟糕的计划是另一回事。

一般来说,最好尝试重写查询 - 如果你使用OR来处理不同的参数集,那么动态SQL(以正确的方式完成,使用带参数的sp_executesql)可以帮助很多

P.S。关于存储过程在运行时运行正常 - 我也看到了这一点 - 我希望它能够生成不同的计划 - 我的怀疑一直是通过例如SSMS启用的SET选项略有不同(在我的实例中).Net - 并且计划在此实例中单独缓存。如果有人可以证实这可能发生,那将不胜感激!

答案 1 :(得分:0)

我怀疑是直接导致这种情况的存储过程,除非它正在执行某种未被清理的锁定/事务逻辑。即使这样,我也看不出丢弃/重新创建会对此产生什么影响。我可能会查看SP正在使用的数据,并尝试使用性能分析来跟踪此执行路径,并查看性能是否可以提高。

答案 2 :(得分:0)

这很可能是为特定过程存储的错误执行计划的结果。

问题(简​​化)是SQL服务器尝试根据传递的参数优化执行计划的使用。在某些情况下,这可能导致可怕的表现。

继承阅读以进一步解释。

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx
http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

从好的方面来说,通过将proc中传递的参数复制到局部变量来解决它非常简单。