SQL性能:重新编译与删除并重新应用存储过程

时间:2013-06-20 21:57:47

标签: sql-server performance stored-procedures

我有一个用于DI报告的存储过程,其中包含使用UNION ALL的62个子查询。最近,性能从不到1分钟到超过8分钟并且使用SQL Profiler,它显示出非常高的CPU和读取。该过程当前已在设置为局部变量的变量中传递,以防止参数嗅探。

将过程的内容作为SELECT语句运行,并且性能恢复到一分钟之内。 在Management Studio中通过EXEC调用该过程并且性能非常糟糕且超过8分钟。 通过EXEC调用程序包括WITH RECOMPILE命令和性能没有改善。我跑DBCC FREEPROCCACHE和DBCC DROPCLEANBUFFERS但仍然没有改进。

最后,我放弃了程序并重新应用它,现在性能恢复了。

任何人都可以帮我解释一下为什么最初的步骤没有纠正程序的性能但是丢弃并重新应用程序呢?

1 个答案:

答案 0 :(得分:0)

听起来像阻塞参数嗅探产生了一个糟糕的计划。当您使用局部变量时,查询优化器使用每列的密度来提出基数估计值,实质上是针对平均值进行优化。如果您的数据分布显着偏差,那么对于某些值,此估计值将显着偏离。这个理论解释了为什么你的初始步骤不起作用。如果阻止参数嗅探,使用WITH RECOMPILE或运行DBCC FREEPROCCACHE将无济于事。它每次都会生成相同的计划。因为你说将过程的内容作为SELECT语句运行使得它更快,所以我认为你实际上需要参数嗅探。但是,如果编译时间可以接受,您还需要尝试使用WITH RECOMPILE,否则存在基于无意识嗅探值而陷入错误计划的风险。