今朝、私の監視ツールを見ると、High Compiles
クエリプランのコンパイルは通常、1秒あたりのバッチ数の15%未満である必要があります。より高い値は、プランの再利用が低いことを示し、プランのコンパイルはCPU集中型の操作になる可能性があるため、CPUの高さと相関することがよくあります。コンパイル数が多いと、プランのキャッシュヒット率が低くなる可能性があり、すべてのプランをキャッシュに保持するための十分なスペースがないため、メモリプレッシャーの指標となる可能性があります。
常に高いコンパイルが表示される場合は、クイックトレースを実行して結果をキャッシュミスで並べ替え、詳細を展開して、実際のコンパイルステートメント(SP:CacheMissイベント、強調表示)と理由(サブクラス)およびプロシージャ(オブジェクト)を表示します。
表面的な調査をしている間、私は下の写真によるとCPUは大丈夫だと気づきました
しかし、私は アドホックワークロード用に最適化 を1に設定しましたが、SQL Serverのメモリ使用量を見ると、バッファキャッシュの代わりにプランキャッシュによってその多くがまだ使用されていることがわかります。下の写真でわかるように。
アドホックワークロードの最適化オプションを使用して、多くの単回使用のアドホックバッチを含むワークロードのプランキャッシュの効率を向上させます。このオプションを1に設定すると、データベースエンジンは、完全にコンパイルされたプランではなく、バッチが初めてコンパイルされるときに、コンパイルされた小さなプランスタブをプランキャッシュに格納します。これは、プランキャッシュが再利用されないコンパイル済みのプランでいっぱいにならないようにすることで、メモリの負荷を軽減するのに役立ちます。
質問:
プランキャッシュから削除できるものを見つけるにはどうすればよいですか?または、少なくともこの調査をどのように開始しますか?
SQL Serverオプションの設定optimize for ad hoc workloads
は、クエリプランキャッシュ内の高い再コンパイル値を修正するためのソリューションではありません。
ただし、アプリケーションが一度だけ実行され、そうでなければクエリプランのキャッシュスペースを汚染(無駄)する多くのアドホック(したがって名前)クエリを実行している場合は、これは優れたソリューションです。これは、たとえば、ユーザーが結果を確認したいテーブルの列を動的に選択できるアプリケーションにすることができます。
SQL Serverデータベースエンジン(DBE)がクエリを実行し、このクエリが以前に実行されたことがない場合、データベースエンジンはデータへのアクセス方法を決定する必要があります。 DBEがデータにアクセスする最良の方法を決定するとすぐに、この情報をクエリプランキャッシュ(QPC)に格納します。これにより、ユーザーは次回アプリケーションが同じクエリを再度実行するときにメリットがあります(ただし、おそらくわずかに異なる値)。
SQL Server DBEは、アプリケーションでステートメントの実行が必要になるたびにQPCを検索します。 DBEがQPCで適切なクエリプランを見つけると、そのクエリプランを選択してデータを取得します。ただし、DBEがQPCで適切なクエリプランを決定できない(QPCのクエリで見つからない、またはタイムアウト値に達した)場合、DBEは新しいクエリプランを作成します。これは、観察しているコンパイル結果です。
ただし、根本的な原因はさまざまです。
SQL Serverはメモリの負荷がかかっている可能性があり、十分なコンパイル済みクエリプランをQPCに保存できません。 DBEは古い計画を追い出し、新しい計画を挿入します。 (解決策:SQL Serverインスタンスにメモリを追加してください)
実際、アプリケーションは、これまで実行されたことのない大量のクエリを生成しているか、QPCに保存されているクエリプランとは少し異なる値を持っています。 (解決策:アプリケーションの複雑さを取り除く)
できません。クエリプランはクエリプランキャッシュに属します。 QPCをクリアするか、DBEをそのままにして最善を尽くすことができます。 (クエリプランの選択的な削除は DBCC FREEPROCCACHE( で実行できますが、これはお勧めしません。)
QPCに格納されているクエリプランを特定し、SQL Serverインスタンスのアプリケーションやメモリ設定を最適化します。 (Cigar Loungeのスクリプトを参照して、 sys.dm_exec_cached_plans)のplan_handle列の説明に従って、sys.dm_exec_sql_textや他のDMVと結合します ドキュメント)
次のクエリは、QPCに保存されているすべてのキャッシュされたプランを一覧表示し、他の関連するDMVにリンクして追加情報を取得できます。
SELECT plan_handle, ecp.memory_object_address AS CompiledPlan_MemoryObject, omo.memory_object_address, pages_allocated_count, type, page_size_in_bytes FROM sys.dm_exec_cached_plans AS ecp JOIN sys.dm_os_memory_objects AS omo ON ecp.memory_object_address = omo.memory_object_address OR ecp.memory_object_address = omo.parent_address WHERE cacheobjtype = 'Compiled Plan'; GO
参照: sys.dm_exec_cached_plans(Transact-SQL) (Microsoft Docs)
クエリの実行を高速化するために、SQL Serverによってキャッシュされる各クエリプランの行を返します。この動的管理ビューを使用して、キャッシュされたクエリプラン、キャッシュされたクエリテキスト、キャッシュされたプランが使用するメモリの量、およびキャッシュされたプランの再利用カウントを見つけることができます。