【问题标题】:SQL performance: Recompile versus drop and re-apply for stored procedureSQL 性能:重新编译与删除并重新申请存储过程
【发布时间】:2013-06-17 22:55:20
【问题描述】:

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

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

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

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

【问题讨论】:

  • 运气? DBCC FREEPROCCACHE 将清除计划缓存,因此不会有任何旧计划出现。具有 62 个子查询的查询的编译时间可能很重要,因此在编译超时之前它到达的位置可能只是运气。
  • 我喜欢运气并且经常帮助我。只是让上级更难解释我们如何、为什么以及如何避免或防止未来发生。将不情愿地添加删除程序作为故障排除步骤,以便在时间敏感时恢复并运行。
  • 在执行计划中是“Reason For Early Termination”“超时”?

标签: sql-server performance stored-procedures


【解决方案1】:

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

【讨论】:

  • 但这并没有解决为什么(显然)他们在DROP ... CREATE 之后得到了一个可接受的计划,而代码(大概)没有改变。
  • @Martin - 真的。那个很奇怪。
  • 过去,参数嗅探导致性能不佳,即添加局部变量并产生昼夜差异。如果性能再次变差,很可能会重新编写或分解它,因为我们需要在 SSRS 报告查看器的默认超时范围内工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多