3

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

我们遇到了一个越​​来越频繁发生的问题。

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

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

这个问题一直存在于这个存储过程中,直到我们删除并重新创建它,得到大量超时。每个 sp 调用都有不同的参数。就像让我获得与当前用户有关的所有未签名班次一样,因此当前用户作为参数传入

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

我们的发布周期是两周,并且在此期间的任何时候都会发生此错误。它发生在发布一周后的第二天,最后一次是发布后的 12 天。

在每个版本中,我们使用 SQL 多脚本编写所有存储的过程/触发器/函数/视图,每次删除和重新创建自己。

我能想到的是存储的过程执行计划已损坏/出错,并且删除重新创建它可以清除这一点。

我正在考虑调用带有重新编译选项的 sps,这是禁止的吗?或可接受的方式

4

3 回答 3

3

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

如果您有“可选”参数 -可以传递NULLOR一个值,并且您在WHERE子句中使用来处理这个问题,那么这通常会导致这种事情。

WITH RECOMPILE 可能会导致大量 CPU 每次编译计划 - 如果存储过程被调用很多,那么这很容易对服务器的一般性能产生影响 - 这个操作系统是否超过了坏的影响计划是另一回事。

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

PS关于存储过程在您运行时工作正常-我也看到过-我希望这取决于生成不同的计划-我一直怀疑通过例如SSMS运行时SET启用的选项集与(在我的例子中).Net - 并且计划在这个例子中被单独缓存。如果有人可以验证这可能会发生,将不胜感激!

于 2011-06-26T23:24:11.423 回答
0

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

于 2011-06-26T23:18:41.320 回答
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 -做关于它/

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

于 2011-06-26T23:29:46.197 回答