我从一个网站查询需要15-30秒,而同一查询在0.5秒内从SQL Server Management工作室运行.我无法使用SQL事件探查器看到任何锁定问题,也无法从SSMS手动重现延迟.一个星期前,我分离并重新连接数据库,似乎奇迹般地解决了这个问题.今天当问题又重新出现时,我只是试图重建索引.这也解决了这个问题.但是,我认为这不一定是索引问题,因为根据我的知识,索引不会在简单的分离/附加上自动重建.
知道什么可能导致延迟吗?我的第一个想法是,可能有一些参数嗅探正在调用的存储过程(所述存储过程运行CTE,如果这很重要)导致错误的查询计划,这将解释问题的间歇性.由于分离/重新附加和索引重建在理论上应该使缓存的查询计划无效,这是有道理的,但我不确定如何验证这一点.另外,为什么在通过SSMS手动运行时,相同的查询(直接从带有完全相同参数的SQL事件探查器复制)会出现相同的延迟?
有什么想法吗?
我知道我很晚才讨论这个话题,但是我想发布一个我遇到类似问题的解决方案.简而言之,在我的程序开始时添加SET ARITHABORT ON命令使网站查询性能与SQL Server工具的性能一致.当您从QA或SSMS运行查询时,通常会在连接上设置此选项(您可以更改该选项,但这是默认选项).
就我而言,我有大约15种不同的存储过程,它们在相当大的数据集(10到100万行)中进行数学聚合(SUM,COUNT,AVG,STDEV) - 添加SET ARITHABORT ON选项将它们全部从每次运行3-5秒至20-30ms.
所以,希望这有助于其他人.
如果缓存了错误的计划,那么如果您使用相同的参数运行相同的查询,那么也应该从SSMS使用相同的错误计划.
找到根本原因是不可能有更好的解决方案.试图窥视和戳各种设置,希望它能解决问题永远不会给你实际修复的信心.此外,下次系统可能会有不同的问题,你会相信同样的问题重新出现并应用了一个糟糕的解决方案.
最好的办法是捕获糟糕的执行计划.Showplan XML Event Class Profiler事件是您的朋友,您可以获得ADO.Net调用的计划.这是一个非常繁重的事件,因此您应该附加探查器并仅在问题在短时间内显示时捕获它.
查询IO统计信息也可以提供帮助.RPC:已完成且SQL:批处理已完成事件都包括读取和写入,因此您可以比较ADO.Net调用与SSMS执行的逻辑IO数量.差异很大(对于完全相同的查询和参数)表示不同的计划.sys.dm_exec_query_stats是另一种调查途径.您可以在那里找到您的查询计划并检查执行统计数据.
如果问题是一个糟糕的计划或其他原因,所有这些应该有助于确定.