如何解决sql server性能问题

时间:2010-08-13 16:25:37

标签: sql-server performance stored-procedures

好的,这个普遍的问题在过去的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

2 个答案:

答案 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)

马丁完全正确。但我会加上2美分来总结:

  1. 显然, SSMS和您的应用使用不同的执行计划
  2. 为什么?因为您的应用使用了缓存计划,默认情况下,SSMS会告诉服务器始终创建新计划。
  3. 快速而肮脏的解决方案 - 清除缓存
  4. 运行此

    DBCC FREEPROCCACHE
    

    有90%的时间帮助。

    PS。 (IMO)说,你重启了你的服务器。服务器仍在忙着启动等,但您的Web应用程序已经开始从用户获取http请求!所以你可怜的小SQL开始创建和缓存执行计划......同时做很多其他事情!这就是重启繁忙机器后执行计划远非最佳的原因......