好的,这个普遍的问题在过去的6个月内两次出现了丑陋的头脑(不同的存储过程)。我们的内部用户报告了应用程序中的超时错误。我们可以在受控环境中重现应用程序中的问题。因此,我们通过使用sp_who2检查阻塞的常规步骤。一切看起来都很好,没有阻挡。因此,我们执行sql跟踪以确切了解该过程的执行方式。我们将它复制到SQL Management Studio中的一个新窗口,并执行sql trace告诉我们ADO.Net正在执行的操作,并在几毫秒内完成。我们的应用程序超时为30秒。几个月前发生这个问题时,我们有SQL Server 2005.我们现在已升级到SQL Server 2008 R2。什么是下一步诊断这样的问题?
@Martin:感谢您的回复。我会详细阅读你的帖子,让你知道我发现了什么。在此之前,这是您请求的SP中的sql:
Select
@Exists=0,
@EarnRecId=0,
@SuppStatusId = 0,
@SLRecId = 0,
@EarnRecDS = Null
Select
@EarnRecId = er.EarningsId,
@EarnRecDS = Convert(Varchar(26),er.Datestamp, 109),
@SuppStatusId = s.SuppStatusId,
@SLRecId = s.SLId
From
Tracking tr
Inner Join Supps s On s.SuppId = tr.SuppId
Inner Join Earnings er On er.EarnRecId = s.SuppId
Where
tr.ClaimId = @ClaimId
and er.FiscalYr = @FiscalYr
And er.EmplyrId In (@EmpId1,@EmpId2)
If @EarnRecId > 0
Begin
Set @Exists=1
End
答案 0 :(得分:4)
可能是参数嗅探。
当调用存储过程并且缓存中没有匹配连接的set
选项的现有执行计划时,将使用在该调用中传递的参数值编译新的执行计划。
有时这会在传递的参数不典型时发生(例如具有异常高的选择性),因此生成的计划将不适合大多数具有不同参数的其他调用。
SSMS对选项SET ARITH_ABORT
有一个不同的默认值,因此当您在SSMS中执行存储过程时,不会得到相同的问题计划。
下次发生问题时,调查问题的最简单方法可能是启用2个单独的SSMS窗口并启用“包含实际执行计划”选项,并在其中执行
SET ARITHABORT OFF
EXEC YourProc ...
而在另一个
SET ARITHABORT ON
EXEC YourProc ...
假设默认的ADO.NET和SSMS连接选项,第一个应该使用缓存中的错误计划。
如果这对您不起作用,您可以使用分析器来查看您需要使用哪些其他设置选项来获取错误的计划或仅使用分析器来直接获取执行计划 - 或者您可以从DMV中检索它们如下。
select p.query_plan, *
from sys.dm_exec_requests r
cross apply sys.dm_exec_query_plan(r.plan_handle) p
where r.session_id = <spid of your ADO.NET connection>
您可能会发现有问题的计划正在进行数以万计的单个索引搜索,而良好的计划可以避免这种情况。
答案 1 :(得分:0)
运行此
DBCC FREEPROCCACHE
有90%的时间帮助。
PS。 (IMO)说,你重启了你的服务器。服务器仍在忙着启动等,但您的Web应用程序已经开始从用户获取http请求!所以你可怜的小SQL开始创建和缓存执行计划......同时做很多其他事情!这就是重启繁忙机器后执行计划远非最佳的原因......