SQL Server 2005のインスタンスをプロファイリングしていますが、PerfMonのSQLServer:SQL Statistics - SQL Compilations/sec
メトリックを使用して、平均が約170程度であることを確認しました。
SQLプロファイラーを作成し、SP:CompileまたはSQL:Compileイベントを探しました。どうやらそれらは存在しません。 Stored Procedure/SP:Recompile
とTSQL/SQL:StmtRecompile
のイベントが見つかりました。プロファイラーに表示されるデータの量から、これらは確認すべきイベントではないことがわかりますが、よくわかりません。
だから私の質問。これらのいずれかに対する答えは素晴らしいでしょう。
Stored Procedure/SP:Recompile
およびTSQL/SQL:StmtRecompile
イベントに関して...これらには、Durationメトリックが含まれていません。これらのイベントがシステムへのタイミングの影響を確認する方法を提供しない場合、システムへのこれらのイベントの影響をどのように測定できますか。SQLコンパイル/秒は適切なメトリックですが、バッチリクエスト/秒と組み合わせた場合のみです。それ自体では、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トレースを介してキャプチャされた期間については、再コンパイルイベントでは使用できません。ケースバイケースの状況でできることはあまりないので、計画のコンパイルが引き起こしている期間や痛みを確認することはそれほど重要ではありません。解決策は、プランの再利用(パラメーター化されたクエリ、ストアドプロシージャなど)を通じてコンパイルと再コンパイルを制限することです。
PerfMon(または別のサードパーティソリューション)を使用して記録する必要がある3つの関連するカウンターがあります。重要な点はrecordこれらの統計をどういうわけかです。
Thomas Stringerが言及した のように、コンパイル/バッチリクエストの比率に注意することは良いことです。明らかに、低い方が良いですが、「良い」ものにはガイドラインがあり、許容できるものを決定できるのはあなただけです。コンパイルの数を減らすことによって得られるパフォーマンス向上の絶対量は、多くの要因に依存します。
また、クエリプランの再利用の量を把握するために、再コンパイル/コンパイルの比率も確認します。繰り返しますが、低いほど良いです。ただし、この場合は、統計情報が変化したときにシステムで再コンパイルを実行する必要があります(DBが読み取り専用で再コンパイルしている場合...何かが間違っている可能性があります)。前に言ったように、何が「良い」かについてのガイドラインしかありません。
あなたが本当にやりたいことは、これらの数値を時間の経過とともにトレンド分析することです。そのため、どちらかの比率に大きなスパイクが見られる場合、クエリプランを正しく使用していないものが展開されます(理想的には、これはテスト中に捕捉されます)。犯人を見つけるための分析クエリ。さらに、頻繁に再コンパイルされるクエリを見つける方法を次に示します。
SELECT TOP 50
qs.plan_generation_num,
qs.execution_count,
qs.statement_start_offset,
qs.statement_end_offset,
st.text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE qs.plan_generation_num > 1
ORDER BY qs.plan_generation_num DESC
CPU使用率の統計も記録している場合は、すべての統計を相互に関連付けて、どの程度の痛みがあり、修正がどれだけ役立つかを確認できます。実際には、コアsprocでの単一の不適切なクエリプラン戦略でも、サーバーをひどく傷つける可能性があることがわかりました。明らかにYMMV。