【问题标题】:Detecting/Monitoring for parameter sniffing problems检测/监控参数嗅探问题
【发布时间】:2011-04-14 16:17:01
【问题描述】:

是否有任何工具可以专门监视/检测参数嗅探问题,而不是那些报告需要很长时间的查询?

我刚刚遇到参数嗅探问题。 (这并不太严重,因为如果正确缓存它会导致报告运行大约需要 2 分钟而不是几秒钟,如果重新编译可能需要 30 秒。而且由于该报告通常每月只运行几次,所以它是问题不大)。

但是,由于我写了报告并且知道它做了什么,我很好奇并去调查和使用 SQL Profiler,我可以在查询计划中看到估计行数为 1 的部分,但实际行数行数是几十万。

所以,让我印象深刻的是,如果 SQL 有这些数字,(或者至少可以得到这些数字),那么也许有某种方法可以让 sql 跟踪和报告哪些计划明显超出。

【问题讨论】:

  • 否(除了捕获所有实际执行计划,这将非常昂贵!)。有一些请求能够通过扩展事件来跟踪这类基数错误,但目前还没有。我想你可以在sys.dm_exec_procedure_stats 中查看最小值和最大值之间差异很大的过程。
  • @Martin 无需捕获执行计划 - 它们都已在计划缓存中可用。
  • @Kragen - Actual Rows 仅在实际计划中可用。 OP 正在尝试找出估计行与实际行之间存在差异的情况。
  • @Martin,由于这是一条评论,我无法将其标记为已接受的答案。 (如果你想添加一个简单地说“不”的答案,我会接受)。

标签: sql-server performance monitoring


【解决方案1】:

你有几个问题:

是否有任何工具可以专门监控/检测参数嗅探问题,而不是那些报告需要很长时间的查询?

要捕捉到这一点,您需要监视过程缓存以找出查询的执行计划何时从好变为坏。 SQL Server 2008 通过将 query_hash 和 query_plan_hash 字段添加到 sys.dm_exec_query_stats 使这变得容易得多。您可以将当前查询计划与相同 query_hash 的过去计划进行比较,当它发生变化时,将旧查询与新查询的逻辑读取次数或工作时间量进行比较。如果它猛增,您可能会遇到参数嗅探问题。

再一次,有人可能刚刚删除了索引或更改了正在调用的 UDF 中的代码,或者更改了 MAXDOP 或影响查询计划行为的一百万个设置中的任何一个。

您想要的是一个单一的仪表板,该仪表板可以汇总显示最消耗资源的查询(因为您可能会在非常频繁地调用但每次消耗少量资源的查询中遇到此问题),然后显示更改它随着时间的推移执行计划,加上系统和数据库级别的更改。 Quest Foglight Performance Analysis 这样做。 (我曾经为 Quest 工作,所以我知道这个产品,但我在这里不先令。)请注意,Quest 销售一个单独的产品,Foglight,它与性能分析无关。我不知道有任何其他产品涉及到这种详细程度。

我可以在查询计划中看到一个部分,其中估计行数为 1,但实际行数为数十万。

这不一定是参数嗅探——例如,这可能是错误的统计数据或表变量使用情况。为了解决这类问题,我喜欢免费的SQL Sentry Plan Advisor 工具。在 Top Operations 选项卡中,它突出显示了估计行和实际行之间的差异。

现在,一次只针对一个计划,您必须先了解该计划。您想 24/7 全天候执行此操作,对吗?当然可以 - 但它是计算密集型的。过程缓存可能很大(我有超过 100GB 的过程缓存的客户端),而且都是未索引的 XML。要比较估计行与实际行,您必须分解所有 XML - 并记住过程缓存在负载下可能会不断变化。

您真正想要的是一种产品,它可以非常快速地将整个过程缓存转储到数据库中,在其上添加 XML 索引,然后将估计值与实际行进行比较。我可以想象一个脚本可以做到这一点,但我还没有看到。

【讨论】:

    【解决方案2】:

    你说

    "估计行数是1,但实际行数是几十万。"

    这可能是由没有统计信息的表变量引起的。

    检测参数嗅探很困难,但您可以通过运行 sp_updatestats 来验证它是否正在发生。如果问题消失,则很可能是参数嗅探。如果不是,那么您还有其他问题,例如表变量太大

    我们现在一直使用参数掩码(系统是在 SQL Server 2000 上开发的)。我们在 99.9+ % 的时间里不需要它,但

    【讨论】:

      【解决方案3】:

      您可以设置一个跟踪来记录所有批处理/存储过程运行的持续时间> Ns的查询文本。

      您显然需要为您的系统定制 N(并且可能添加规则以排除即使在正常执行期间也需要很长时间的批处理作业),但这应该确定哪些查询提供最差的性能,并且还会记录任何查询(以及及其参数)执行时间异常长 - 可能是参数嗅探问题的结果。

      请参阅How to create a SQL trace using T-SQL,了解如何使用 T-SQL 创建跟踪。这将提供比使用 SQL Profiler 更好的性能,因为它只捕获您为其设置跟踪事件的事件(据报道,SQL Profiler 捕获所有事件,然后在应用程序中过滤它们)。

      【讨论】:

      • 我知道这一点,这就是为什么我的问题仅根据查询所需的时间专门排除了解决方案。这需要单独检查每个查询以确定它是否真的需要花费这么长时间,这意味着只对极少数最糟糕的查询执行此操作。
      • @sgmoore 好吧,我想您可以查看计划缓存并分析每个缓存,但是除非查询实际上很慢,否则努力解决这些“问题”真的有任何意义吗?跨度>
      • 这正是重点,如果您必须依次分析每个查询,那是不值得的。另一方面,如果您可以让 SQL 为您完成所有艰苦的工作,那么它可能非常值得。
      • @sgmoore 分析器可以为您标记查询,但它无法神奇地解决为什么查询很慢 - 您需要自己做这件事 更难。
      猜你喜欢
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 2016-10-07
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      相关资源
      最近更新 更多