执行计划缓存

 


 

执行计划编译是需要时间的,为了提高效用率,是要缓存的,可用如下方式查看:
–查看执行计划的缓存

SELECT UseCounts,RefCounts, Cacheobjtype, Objtype,dbid,
ISNULL(DB_NAME(dbid),'ResourceDB') AS DatabaseName, TEXT AS SQL
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
ORDER BY dbid,usecounts DESC;

 SELECT cacheobjtype,objtype,sql FROM sys.syscacheobjects a
 WHERE cacheobjtype = 'compiled plan' AND dbid = 7

 
–清空执行计划缓存
DBCC FREEPROCCACHE
GO
–从缓存中清除给定数据库的计划缓存
DBCC FLUSHPROCINDB(<dbid>)
GO

执行计划重新编译放到缓存中的时机:
1,表或视图的架构发生了更改,索引发生了改变造成统计信息发生更改。
2,运行了sp_recompile
3,执行计划被清除,如服务器重启,服务重启,放在内存中的执行计划就会被清空。
4,缓存会用LRU算法找出很少使用的,然后从内存中删除,在sys.dm_exec_query_stats中有一字段creation_time标识计划的创建时间,一般一、两个小时就会重新建立一份的。
可通过观察以下事件看缓存的变更。SP:CacheInsert SP:CacheMiss SP:CacheHit

执行计划要保持重用,以提高利用率,可以查出经常重新编译的sql以做优化,当然重用并不一定好,因为执行计划不适合,如参数化问题等。

sys.dm_exec_query_stats 有一个栏位plan_generation_num,计划编译次数,可用此来分析最常编译的计划。
select top 25
    plan_generation_num,
    SUBSTRING(qt.text,qs.statement_start_offset/2+1,
        (case when qs.statement_end_offset = -1
        then DATALENGTH(qt.text)
        else qs.statement_end_offset end -qs.statement_start_offset)/2 + 1)
        as stmt_executing,
    qt.text,
    execution_count,
    sql_handle,
    dbid,
    db_name(dbid) DBName,
    objectid,
    object_name(objectid,dbid) ObjectName
from sys.dm_exec_query_stats as qs
    Cross apply sys.dm_exec_sql_text(sql_handle) qt
where plan_generation_num >1
--AND qs.last_execution_time >='2011-08-28 10:00' 限定时间
order by plan_generation_num desc
原文地址:https://www.cnblogs.com/heqianjin/p/5698593.html