3

每隔几个月,网站的几个精选页面就会开始响应

超时已过。在操作完成之前超时时间已过或服务器没有响应。

我运行 SQL Server Profiler 来查看数据库挂起的位置。它在一个特定的存储过程上。所以我接受了存储过程调用并通过 Management Studio 运行它。在一秒钟内返回几千行。

打开程序,我看到它只是一个简单的选择语句。如果我取出 select 语句并在新的查询窗口中运行它,Management Studio 将挂起。

所以我开始分段运行它,并找到导致查询挂起的行

and GetDate() between EffectiveDate and ISNULL(ExpiryDate, @CurrentDate) 

GetDate()@CurrentDate反正应该是这样,所以如果我切换它,它会运行良好。为什么这很重要?据我了解,GetDate不应该是一个昂贵的电话。我理解IsNull是,但这也不重要,因为如果我将 GetDate 换成 CurrentDate,它就可以很好地处理查询。

我是否正确假设getdate导致此查询间歇性挂起?它如何/为什么要这样做?

一些背景知识,正如我所说,这个错误之前曾在 3 月 23 日、7 月 27 日、10 月 25 日和现在的 11 月 21 日出现。它似乎总是在接近月底的时候发生。我确信在此期间没有任何事情发生(计划任务、维护等)

这是在生产服务器上,所以我实际上无法花时间调试问题。网站一旦宕机,就必须恢复。我知道如何解决它,我只需要对存储过程强制重新编译,但有谁知道可能是什么原因造成的?

SQL Server 也有另一个 UAT 数据库,同样的过程也会挂在那个数据库上。但是具有完全相同的代码行的其他存储过程在两个数据库上都可以正常运行。

编辑:我不得不把网站备份,所以我重新编译了存储过程。该网站现在运行良好。不过,查询仍然不能自行运行。

4

1 回答 1

0

我弄错了问题的原因。我分段运行的查询基本上是:

select *
from Item
left outer join category Subcategories on Subcategories.ItemKey = Item.Id,
Categories Category,
Availability
where Item.Id = @ItemId
  and GetDate() between Availability.EffectiveDate 
      and ISNULL(Availability.ExpiryDate, @CurrentDate) 

这显然不是在生产中运行的查询,只是一个匿名示例。

此查询不会运行。为了让它运行,我最初注释掉了

and GetDate() between EffectiveDate and ISNULL(ExpiryDate, @CurrentDate)

如果我更改GetDate()@CurrentDate. 我确定GetDate是问题所在。但是,当我运行查询并注释掉该Availablity行时,它运行良好。Availability是一张巨大的桌子。我运行了重新索引和统计更新,一切正常。我想我应该GetDate道歉。

编辑:这再次发生在完全不同的环境中。似乎GetDate又是罪魁祸首。更改该行并运行该程序使一切恢复正常。GetDate可能不应该归咎于根本原因,但这绝对是出现问题的第一个迹象。

于 2011-11-22T15:55:35.440 回答