最近我们遇到了一个性能问题,通过执行DBCC freeproccache...Now解决了这个问题,我们还有很多问题要回答;
任何帮助都是非常感谢的!
发布于 2011-08-19 22:38:34
你的问题到处都是,所以我会尽力解决这些问题。过程缓存只有这么大。您的过程缓存可能已填充了单用途计划(这对统计信息没有影响,尽管统计信息会影响计划缓存)。您可以在金伯利特里普的博客文章"特别工作负载的计划、缓存和优化“中看到很多关于单一用途计划的详细信息,其中包括一个针对计划的查询,该查询将帮助识别缓存何时填充了大量的单一用途计划。正如她建议的那样,您可以通过对临时工作负载使用优化来防止这种膨胀。如果您发现需要经常这样做,我会说,将空闲缓存调度为一项任务是一种辅助手段,而不是解决方案。
为了清除“坏”计划,首先你需要识别“坏”计划。这可能是一个超过一定大小和/或在一段时间内没有执行的计划,或者是通过长期运行的查询来识别的,等等。不幸的是,除非您已经知道了受影响的查询或查询,否则识别一个受参数嗅探影响的计划并不简单。让我们假设您希望在缓存中找到一个多星期没有运行的最古老的计划:
;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明天可能运行的,那么最好还是把它留在那里吧。如果您想要清除该计划,可以直接通过以下方式清除它:
DBCC FREEPROCCACHE([paste plan handle from above query here]);这听起来比在全球运行DBCC FREEPROCCACHE要多得多,但是如果您在缓存中有很多好的计划,那么它肯定会对您的用户更好。
不过,这听起来真的像个绷带。如果您的缓存中装满了垃圾,性能会一直保持到空闲状态,那么您需要在体系结构上查看更高的级别,查询是如何提交的,等等。这是我在LINQ2SQL的第一次迭代中所期望的行为,它将为每个不同长度的字符串参数缓存一个查询计划的版本。因此,如果您的参数为“一月”,您将得到一个与参数“二月”不同的计划,因为它将数据类型定义为VARCHAR(7)与VARCHAR(8)。可以肯定的是,行为是固定的,但我对您的环境/应用程序还不太了解,无法准确地建议在哪里寻找“坏想法”。
https://stackoverflow.com/questions/7127776
复制相似问题