SQL Compilations / secは良い指標ですが、Batch Requests / secと組み合わせた場合のみです。単独では、1秒あたりのコンパイル数はあまりわかりません。
170が表示されています。1秒あたりのバッチリクエストが200にすぎない場合(実際には少し誇張されています)、はい、原因の最下部に到達する必要があります(アドホッククエリと使い捨てプランの過剰使用)。しかし、1秒あたりのバッチ要求が約5000である場合、1秒あたり170のコンパイルはまったく悪くありません。一般的な経験則として、Compilations / secはBatch Requests / secの合計の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トレースを介してキャプチャされた期間に関しては、再コンパイルイベントでは使用できません。ケースバイケースの状況でできることはあまりないので、計画のコンパイルが引き起こす期間や痛みを見るのはそれほど重要ではありません。解決策は、計画の再利用(パラメーター化されたクエリ、ストアドプロシージャなど)によってコンパイルと再コンパイルを制限することです。