简体   繁体   English

DBCC freeproccache?

[英]DBCC freeproccache?

We recently had a performance problem and this got resolved by executing DBCC freeproccache...Now, we have lot more questions to answer; 我们最近遇到了性能问题,并且通过执行DBCC freeproccache解决了这个问题......现在,我们还有很多问题要回答;

  • What made the the procedure cache out dated? 是什么让程序缓存过时了?
  • If indexes or Statistics where out dated, why the query did not recompile itself? 如果索引或统计信息在哪里过时,为什么查询没有重新编译?
  • Is it a good practice to schedule DBCC freeproccache as a JOB? 将DBCC freeproccache安排为JOB是一个好习惯吗?
  • Is there a way to identify potential out dated query plans? 有没有办法识别潜在的过时查询计划?
  • Is there a way to identify an offending query? 有没有办法识别违规查询?

Any Help is appreciated! 任何帮助表示赞赏!

Your questions are all over the place, so I'll try to address them all. 你的问题到处都是,所以我会尽力解决这些问题。 The procedure cache is only so large. 过程缓存只是如此之大。 Your procedure cache may have been filled with single-use plans (this has no impact on statistics, though statistics can impact the plan cache). 您的过程高速缓存可能已经填充了一次性计划(这对统计信息没有影响,但统计信息可能会影响计划高速缓存)。 You can read a lot of details about single-use plans in Kimberly Tripp's blog post, " Plan cache and optimizing for adhoc workloads " - including a query against sys.dm_exec_cached_plans that will help identify when the cache is populated with a lot of single-use plans. 您可以在Kimberly Tripp的博客文章“ 特定工作负载计划缓存和优化 ”中阅读有关一次性计划的大量详细信息 - 包括针对sys.dm_exec_cached_plans的查询,这将有助于确定缓存何时填充了大量单个 -使用计划。 As she suggests, you can prevent this bloating by using optimize for ad hoc workloads. 正如她所建议的那样,您可以通过对ad hoc工作负载使用optimize来防止这种膨胀。 If you are finding the need to do this often, I would say that scheduling freeproccache as a job is a band-aid, not a solution. 如果你发现需要经常这样做,我会说安排freeproccache作为工作是一个创可贴,而不是解决方案。

In order to clear out a "bad" plan, first you need to identify the "bad" plan. 为了清除“坏”计划,首先需要确定“坏”计划。 This could be a plan that exceeds a certain size and/or has not been executed in some time, or that you have identified by a long-running query, etc. Unfortunately it is not simple to identify a plan that is a victim of parameter sniffing unless you already know the query or queries that are impacted. 这可能是超过一定大小和/或在一段时间内未执行的计划,或者您通过长时间运行的查询识别的计划等。遗憾的是,识别作为参数受害者的计划并不简单除非您已经知道受影响的查询或查询,否则请进行嗅探。 Let's assume you want to find the oldest plans in the cache that hasn't been run in over a week: 假设您要在缓存中找到一周内未运行的最旧计划:

;WITH x AS 
(
    SELECT TOP 10 
        qs.[sql_handle], qs.plan_handle,
        txs = qs.statement_start_offset, 
        txe = qs.statement_end_offset,
        [size] = cp.size_in_bytes, 
        [uses] = SUM(cp.usecounts), 
        [last] = MAX(qs.last_execution_time)
    FROM 
        sys.dm_exec_query_stats AS qs
    INNER JOIN 
        sys.dm_exec_cached_plans AS cp 
        ON qs.plan_handle = cp.plan_handle
    WHERE 
        qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP)
    GROUP BY 
        qs.[sql_handle], qs.plan_handle, cp.size_in_bytes,
        qs.statement_start_offset, qs.statement_end_offset
    ORDER BY 
        [size] DESC
) 
SELECT 
    x.plan_handle, 
    size, uses, [last],
    [statement] = COALESCE(NULLIF(
        SUBSTRING(t.[text], x.txs/2, 
          CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END
          ), ''), t.[text]) 
FROM x 
CROSS APPLY sys.dm_exec_sql_text(x.[sql_handle]) AS t;

Now you need to verify that you really want to clear out this plan. 现在您需要确认您确实要清除此计划。 For example, if you recognize that query as something the CEO might run tomorrow, maybe it's best to leave it there. 例如,如果您将该查询视为CEO明天可能会执行的操作,那么最好将其留在那里。 If you want to clear the plan, you can clear it directly by saying: 如果要清除计划,可以直接清除它:

DBCC FREEPROCCACHE([paste plan handle from above query here]);

This sounds like a lot more work than running DBCC FREEPROCCACHE globally, but if you have a lot of good plans in the cache, it is certainly going to be better for your users overall. 这听起来比在全球范围内运行DBCC FREEPROCCACHE要多得多,但如果你在缓存中有很多好的计划,那么对你的整体用户来说肯定会更好。

Still, this really sounds like a band-aid. 不过,这听起来像是一个创可贴。 If your cache is filling up with junk and performance goes in the toilet until you free the cache up, you need to look at a higher level at the architecture, how queries are submitted, etc. This is the behavior I'd expect from the very first iteration of LINQ2SQL, where it would cache a version of a plan for a query for each string argument that was a different length. 如果您的缓存充满了垃圾,并且性能进入厕所,直到您释放缓存,您需要在架构中查看更高级别,如何提交查询等。这是我期望的行为LINQ2SQL的第一次迭代,它会为每个不同长度的字符串参数缓存查询计划的版本。 So if you had a parameter of 'January' you'd get a different plan than with a parameter of 'February' because it would define the data type as VARCHAR(7) vs. VARCHAR(8) . 因此,如果您有一个参数'January',您将得到一个与'February'参数不同的计划,因为它将数据类型定义为VARCHAR(7)VARCHAR(8) Pretty sure that behavior is fixed but I don't know enough about your environment / application to suggest where precisely to look for "bad ideas." 很确定这种行为是固定的,但我对你的环境/应用程序知之甚少,无法建议准确地寻找“糟糕的想法”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM