我有一份每天都有的工作,并执行了几十个存储过程 他们中的大多数都运行得很好,但最近有几个人开始运行一段时间(4-5分钟) 当我早上进来并试图对它们进行故障排除时,它们只需要10-20秒,就像它们应该的那样 这已经发生在过去10天左右。没有对服务器进行任何更改(我们正在运行SQL 2012) 我怎么解决它,我该怎么做才能解决这个问题? 谢谢!!
答案 0 :(得分:1)
您可以使用SQL提供的一些DMV(动态管理视图)来调查计划缓存。然而,结果可能有点令人生畏,如果没有一些背景,可能很难深入研究结果。我建议您查看一些DMV,例如sys.dm_exec_query_stats
和sys.dm_exec_cached_plans
。来自SQLSkills.com的Kimberly Tripp在Pluralsight上做了一些关于如何使用它们的GREAT课程,并通过从这些DMV中构建更高级的查询来获得一些非常棒的结果。
同样,这些DMV将返回一个plan_handle列,您可以将该列传递给另一个DMV sys.dm_exec_query_plan(plan_handle)
,以返回特定语句的执行计划。困难的部分是挖掘dm_exec_cached_plans
的结果,以找到导致问题的特定作业/存储过程。 sys.dm_exec_sql_text(qs.[sql_handle])
可以通过提供为该作业运行的SQL的快照来提供帮助,但是通过CROSS APPLY
将其与其他一些DMV一起使用,您将获得最大的收益(在我看来)我提到。如果您可以识别Job / Proc / Statement并查看计划,它可能会向您显示Sean Lange提到的参数嗅探问题的一些指示。
以防万一:参数嗅探就是当你运行查询/存储过程的第一个实例时,SQL会查看你传入的参数并根据它构建一个计划。从初始编译的查询/ proc生成的计划对于您传入的特定参数是理想的,但可能不适合其他参数。想象一个高度倾斜的表,其中所有日期都是'01 -01-2000',除了一个'10 -10-2015'。
由于数据选择性,传递这两个参数将产生截然不同的计划(读:数据有多独特?)。如果其中一个计划被保存到缓存并为每个后续执行调用,则可能(在某些情况下,可能)它不适合其他参数。
你看到Job之间的速度和你自己运行命令之间的速度差异的可能原因是,当你运行它时,你正在运行Ad Hoc。作业不是,它将它们作为存储过程运行,这意味着它们将使用不同的执行计划。
<强> TL; DR:强> 您为作业保存的执行计划未进行优化。但是,当您手动运行它时,您可能会创建针对该SPECIFIC运行进行了优化的Ad Hoc计划。挖掘计划缓存并查看正在发生的事情是一条艰难的道路,但它是100%值得的。我强烈推荐查找Kimberly Tripp的博客,因为她有一些关于此的精彩帖子以及关于Pluralsight的一些精彩课程。