この再コンパイルの原因となるものに関するドキュメントはどこにも見つかりません。クエリの突然のパフォーマンスの低下を調査しています。考えられる唯一のことは、小さなデータセットに対して実行されたときに計画がパラメータ化されたクエリ用に再コンパイルされ、行の見積もりがめちゃくちゃになったことです。このプロセスが実行されているとき(数秒ではなく数時間かかった後)、tempdbにかなりの負荷がかかっていることがわかりました。消費されたテーブルの統計は変更されず、再コンパイルの理由のリストで意味のある他の唯一の理由は、#12「パラメーター化されたプランがフラッシュされた」です。
問題のプロセスは、ビューを呼び出し、単一のINT列でフィルタリングしていました。これはEntity Frameworkを通じて行われました。クラスに存在するエンティティキーは1つだけで、ビューのメインテーブルのPKです。すべてのレコードは一意です。
"Parameterized plan flushed"が原因でプランが再コンパイルされる理由を説明しているドキュメントを誰かが私に指摘できるかどうか知りたいです。
クエリプランは、いくつかの理由でキャッシュからフラッシュされます。これには、期限切れ、メモリ不足によるフラッシュ、ユーザーアクションによるフラッシュ(DBCC FREEPROCCACHEなど)、再起動によるフラッシュ、および明示的な再コンパイルによるフラッシュ(OPTION(RECOMPILEまたはsp_recompile)が含まれます。 )。
強制的な再コンパイルまたは手動フラッシュの形跡がない場合は、プランが期限切れであるか、メモリの圧力が原因でフラッシュされた可能性があります。 ドキュメントから:計画キャッシュ内部 :
キャッシュから計画を削除することは、そのコストに基づいています。アドホックプランの場合、コストはゼロと見なされますが、プランが再利用されるたびに1ずつ増加します。他のタイプのプランの場合、コストはプランの作成に必要なリソースの測定値です。これらのプランの1つが再利用されると、コストは元のコストにリセットされます。非アドホッククエリの場合、コストはティックと呼ばれる単位で測定され、最大値は31です。コストは、I/O、コンテキストスイッチ、メモリの3つの要素に基づいています。それぞれに31ティックの合計内で最大値があります。
- I/O:各I/Oのコストは1ティックで、最大は19です。
- コンテキストスイッチ:それぞれ1ティック、最大8。
- メモリ:16ページごとに1ティック、最大4。
メモリの負荷がかかっていない場合、キャッシュされるすべてのプランの合計サイズがバッファプールサイズの50%に達するまで、コストは削減されません。その時点で、次のプランへのアクセスにより、すべてのプランのティック単位のコストが1ずつ減ります。メモリ不足が発生すると、SQL Serverは専用のリソースモニタースレッドを開始して、特定の1つのキャッシュ内のいずれかのプランオブジェクトのコストを減分します(ローカルプレッシャー)またはすべてのプランキャッシュオブジェクト(グローバルプレッシャーの場合)。
これを見てください StackExchangeの回答 これは、すばらしいリンクの山と計画の再利用とキャッシングに関する情報を提供します。これが再発した場合は、正確な原因を把握するために監視を行う必要がありますが、このクエリの既知の適切な計画を強制し、回帰を追跡できるようにする Query Store の活用も検討する必要があります。これは他のクエリにも影響を与える可能性があるため、データベース全体で。