SQL编译/秒是一个很好的指标,但仅当与Batch Requests / sec结合使用时。就其本身而言,每秒编译量并不能真正告诉您太多信息。
您将看到170。如果每秒的批处理请求数仅为200(效果有点夸张),则是,您需要深入分析原因(很可能是临时查询和一次性计划的过度使用)。但是,如果您的批处理每秒请求量约为5000,那么每秒170次编译就完全不错。一般的经验法则是,“ 编译/秒”应为“总批处理请求/秒”的 10%或以下。
如果您真的想深入了解正在缓存的内容,请运行以下使用适当DMV的查询:
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
要获得所有一次性使用计划(计数):
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
)
select count(*)
from PlanCacheCte
where usecounts = 1
要获得您与所有缓存计划相比有多少个一次性计数计划的比率:
declare @single_use_counts int, @multi_use_counts int
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
where cp.cacheobjtype = 'Compiled Plan'
)
select @single_use_counts = count(*)
from PlanCacheCte
where usecounts = 1
;with PlanCacheCte as
(
select
db_name(st.dbid) as database_name,
cp.bucketid,
cp.usecounts,
cp.size_in_bytes,
cp.objtype,
st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
where cp.cacheobjtype = 'Compiled Plan'
)
select @multi_use_counts = count(*)
from PlanCacheCte
where usecounts > 1
select
@single_use_counts as single_use_counts,
@multi_use_counts as multi_use_counts,
@single_use_counts * 1.0 / (@single_use_counts + @multi_use_counts) * 100
as percent_single_use_counts
至于通过SQL Server跟踪捕获的持续时间,它不适用于重新编译事件。查看计划编制所导致的持续时间或痛苦并不那么重要,因为对于个案情况您无能为力。解决方案是尝试通过计划重用(参数化查询,存储过程等)来限制编译和重新编译。