首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DBCC免费缓存?

DBCC免费缓存?
EN

Stack Overflow用户
提问于 2011-08-19 21:47:42
回答 1查看 11K关注 0票数 5

最近我们遇到了一个性能问题,通过执行DBCC freeproccache...Now解决了这个问题,我们还有很多问题要回答;

  • 是什么让程序缓存过时了?
  • 如果索引或统计数据过时了,为什么查询没有重新编译自己?
  • 将DBCC空闲缓存调度为作业是一种良好的实践吗?
  • 是否有一种方法可以识别出可能过时的查询计划?
  • 是否有一种方法来识别一个冒犯的查询?

任何帮助都是非常感谢的!

EN

回答 1

Stack Overflow用户

发布于 2011-08-19 22:38:34

你的问题到处都是,所以我会尽力解决这些问题。过程缓存只有这么大。您的过程缓存可能已填充了单用途计划(这对统计信息没有影响,尽管统计信息会影响计划缓存)。您可以在金伯利特里普的博客文章"特别工作负载的计划、缓存和优化“中看到很多关于单一用途计划的详细信息,其中包括一个针对计划的查询,该查询将帮助识别缓存何时填充了大量的单一用途计划。正如她建议的那样,您可以通过对临时工作负载使用优化来防止这种膨胀。如果您发现需要经常这样做,我会说,将空闲缓存调度为一项任务是一种辅助手段,而不是解决方案。

为了清除“坏”计划,首先你需要识别“坏”计划。这可能是一个超过一定大小和/或在一段时间内没有执行的计划,或者是通过长期运行的查询来识别的,等等。不幸的是,除非您已经知道了受影响的查询或查询,否则识别一个受参数嗅探影响的计划并不简单。让我们假设您希望在缓存中找到一个多星期没有运行的最古老的计划:

代码语言:javascript
复制
;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;

现在,您需要验证您是否真的想清除这个计划。例如,如果您认识到这个查询是CEO明天可能运行的,那么最好还是把它留在那里吧。如果您想要清除该计划,可以直接通过以下方式清除它:

代码语言:javascript
复制
DBCC FREEPROCCACHE([paste plan handle from above query here]);

这听起来比在全球运行DBCC FREEPROCCACHE要多得多,但是如果您在缓存中有很多好的计划,那么它肯定会对您的用户更好。

不过,这听起来真的像个绷带。如果您的缓存中装满了垃圾,性能会一直保持到空闲状态,那么您需要在体系结构上查看更高的级别,查询是如何提交的,等等。这是我在LINQ2SQL的第一次迭代中所期望的行为,它将为每个不同长度的字符串参数缓存一个查询计划的版本。因此,如果您的参数为“一月”,您将得到一个与参数“二月”不同的计划,因为它将数据类型定义为VARCHAR(7)VARCHAR(8)。可以肯定的是,行为是固定的,但我对您的环境/应用程序还不太了解,无法准确地建议在哪里寻找“坏想法”。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7127776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档