3

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

将该过程的内容作为 SELECT 语句运行,性能恢复到不到一分钟。通过 Management Studio 中的 EXEC 调用该过程,性能非常糟糕,超过 8 分钟。通过 EXEC 调用过程(包括 WITH RECOMPILE 命令)和性能没有提高。我运行了 DBCC FREEPROCCACHE 和 DBCC DROPCLEANBUFFERS,但仍然没有任何改善。

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

谁能帮我解释一下为什么最初的步骤没有纠正程序的性能,但删除并重新应用程序可以吗?

4

1 回答 1

0

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

于 2013-06-22T22:33:27.180 回答