我有以下问题:当从我的应用程序中调用存储过程时,不时(如1000次调用中的1次),需要10-30秒才能完成。通常,sproc在一秒钟内运行。这是一个相当简单的proc,只有一个选择将几个表连接在一起。所有表名都设置了一个(NOLOCK)提示,因此可能没有锁定。索引也全部到位,否则它会一直很慢。
问题是我无法在SSMS中复制这个问题(因为它始终以亚秒级运行),无论它运行多少次sproc,但是当我将探查器指向正在运行我的应用程序的用户时,我看到了问题。 SSMS中的查询计划似乎是正确的,但问题仍然存在。
我从哪里开始?如何调试此问题?
答案 0 :(得分:5)
一些选项:
探查者或SET STATISTICS xx ON
说什么?是资源饥饿,比如说CPU
引擎决定统计信息已过期。表格是否按行数改变10%(经验法则)。测试:
SELECT
name AS stats_name,
STATS_DATE(object_id, stats_id) AS statistics_update_date
FROM
sys.stats
WHERE
object_id IN (OBJECT_ID('relevanttable1'), OBJECT_ID('relevanttable2'))
服务器上还发生了什么?示例:索引重建:不阻塞,只占用资源。
通常我建议参数嗅探,但你说每个调用的参数都是相同的。我也期望它更频繁地发生。
答案 1 :(得分:4)
答案 2 :(得分:2)
我会在SQL Server Profiler中设置一个跟踪,以查看应用程序用于连接的SET选项设置,以及SSMS中正在使用的设置。通过SET选项设置,我的意思是
ARITHABORT
ANSI_NULLS
CONCAT_NULL_YIELDS_NULL
//etc
查看MSDN以获取选项表
我之前看到SSMS和应用程序之间使用的set选项不同的问题(在特定情况下,它是ARITHABORT
)并且性能差异很大(实际上,应用程序会超时)对于某些查询,取决于参数值。)
这是我建议开始调查的地方。通过设置跟踪,您将能够看到哪些特定呼叫花费的时间更长以及正在使用的参数。
答案 3 :(得分:1)
在运行缓慢的运行中,传递给proc的参数有什么不同吗?
答案 4 :(得分:1)
您是否完全确定它是数据库查询,而不是代码中的其他相邻逻辑? (即你之前和之后是否立即加上带时间戳的“追踪”陈述?)
答案 5 :(得分:1)
我还会关注数据类型的强制。也就是说,当varchar(60)参数与varchar(80)数据进行比较和索引时,我看到了类似的问题。在某些情况下,SQL Server会失去理智并强制扫描而不是搜索 - 尽管如此,我相信在这种情况下,您通常会在执行计划中看到这种情况。
可悲的是,另一个潜在的罪魁祸首(我有点怀疑因为它可能是一个红色的鲱鱼而抛出它)是超线程的。我已经看到它在过去[1]中做了类似的事情。答案 6 :(得分:0)
重新编译存储过程然后看看会发生什么。这实际上有所帮助。
答案 7 :(得分:0)
我也有类似的性能问题。 将 WITH RECOMPILE 添加到SP有帮助。
这不是我所寻求的解决方案,但到目前为止我找不到更好......