WITH RECOMPILEオプションを使用する場合の経験則
-
05-07-2019 - |
質問
WITH RECOMPILEオプションを使用すると、オプティマイザーがストアドプロシージャのクエリプランを再構築することを強制しますが、いつそれを実行しますか?
WITH RECOMPILEオプションを使用する場合と使用しない場合の経験則は何ですか?
すべてのsprocにそれを置くことに関連する効果的なオーバーヘッドは何ですか?
解決
他の人が言ったように、習慣としてすべてのストアドプロシージャに WITH RECOMPILE
を単純に含めたくありません。そうすることで、ストアドプロシージャの主な利点の1つ、クエリプランを保存するという事実を排除することになります。
なぜそれが大したことになるのでしょうか?クエリプランの計算は、通常の手続き型コードをコンパイルするよりもはるかに集中的です。 SQLステートメントの構文は what を指定するだけで、(一般的に)方法を指定しないため、物理データベースを作成する際にデータベースに幅広い柔軟性を与えます。計画(つまり、実際にデータを収集して変更するための段階的な指示)。 「トリック」がたくさんあります。データベースクエリプリプロセッサが実行できることと選択できること-テーブルを結合する順序、使用するインデックス、結合の前後に WHERE
句を適用するかどうかなど
単純なSELECTステートメントの場合、違いはないかもしれませんが、重要でないクエリの場合、データベースは(通常のマイクロ秒ではなくミリ秒単位で)かなりの時間を費やして、最適な計画。本当に複雑なクエリの場合、最適な計画を保証することさえできず、ヒューリスティックを使用してかなり良い計画を考え出す必要があります。そのため、毎回強制的に再コンパイルすることにより、以前の計画が完全に良好だったとしても、そのプロセスを何度も繰り返す必要があることを伝えています。
ベンダーに応じて、クエリプランを再コンパイルするための自動トリガーが必要です-たとえば、テーブルの統計が大幅に変化した場合(たとえば、特定の列の値のヒストグラムが時間とともに均等に分散し始めると、 )、DBはそのことに気付き、計画を再コンパイルします。しかし、一般的に言えば、データベースの実装者は、あなたよりも全体的に賢くなります。
パフォーマンスに関連するものと同様に、暗闇の中で撮影しないでください。パフォーマンスの90%を犠牲にしているボトルネックがどこにあるかを把握し、最初に解決します。
他のヒント
クエリプランをコンパイルするのは比較的コストのかかる操作であり、クエリプランをキャッシュして再利用してもメリットは見られないため、すべてのストアドプロシージャに置くことはお勧めできません。
ストアドプロシージャ内に構築された動的なwhere句のケースは、 WITH RECOMPILE
をストアドプロシージャに追加するのではなく、 sp_executesql
を使用してTSQLを実行することで処理できます。
別の解決策(SQL Server 2005以降)は、 OPTIMIZE FOR
ヒントを使用して特定のパラメーターでヒントを使用することです。行の値が静的な場合、これはうまく機能します。
SQL Server 2008では、あまり知られていない機能と呼ばれる" 最適化のために最適化
":
このヒントはクエリオプティマイザーに指示します 標準のアルゴリズムを使用するには パラメータ値がない場合は常に使用されます クエリに渡されていました。 この場合、オプティマイザーは 利用可能なすべての統計データで 何の決定に達する に使用されるローカル変数の値 クエリプランを生成する必要があります、 特定のものを見る代わりに に渡されたパラメーター値 アプリケーションによるクエリ。
最も一般的な使用法は、プロシージャに動的WHERE句がある場合です...特定のクエリプランがコンパイルされ、後続の実行のために保存されるのは、まったく同じ句ではない可能性があるためです次にプロシージャが呼び出されたとき。
通常、 WITH RECOMPILE
のより優れた代替手段は、 OPTION(RECOMPILE)
です。
この質問の回答から取られた以下の説明でわかるように>
パラメータ感度の問題が発生すると、一般的な フォーラムやQ& Aサイトに関するアドバイスは、「再コンパイルを使用する」ことです。 (仮定 前述のその他のチューニングオプションは不適切です)。残念ながら、 そのアドバイスは、WITH RECOMPILEを追加することを意味すると誤解されることがよくあります。 ストアドプロシージャのオプション。
WITH RECOMPILEを使用すると、効果的にSQL Server 2000に戻ります すべてのストアドプロシージャが毎回再コンパイルされる動作 実行。 SQL Server 2005以降でのより良い代替手段は、 OPTION(RECOMPILE)クエリヒントを使用するステートメントは、 パラメータスニッフィングの問題があります。このクエリヒントの結果 問題のあるステートメントのみの再コンパイル。実行計画 ストアドプロシージャ内の他のステートメントはキャッシュされ、再利用されます 普段通り。
WITH RECOMPILEを使用すると、保存された プロシージャはキャッシュされません。その結果、パフォーマンス情報はありません sys.dm_exec_query_statsなどのDMVで維持されます。クエリを使用する 代わりに、コンパイル済みプランをキャッシュできることを意味し、パフォーマンス DMVで情報を入手できます(ただし、 最近の実行、影響を受けるステートメントのみ)。
少なくともSQL Server 2008ビルド2746(サービス 累積更新プログラム5)を含むパック1、OPTION(RECOMPILE)を使用して別の WITH RECOMPILEに比べて大きな利点:OPTION(RECOMPILE)のみ パラメータ埋め込み最適化を有効にします。
反復データとコンテキストを使用したテストで無効なクエリプランが生成されることを示す場合にのみ使用する必要があります(考えられる理由は何でも)。 SPが適切に最適化されないことを事前に(テストなしで)想定しないでください。
手動呼び出しのみの唯一の例外(つまり、SPにコーディングしないでください):ターゲットテーブルの文字を大幅に変更したことがわかっている場合。例えば切り捨て、一括読み込みなど
時期尚早な最適化のもう1つの機会です。
注:たくさんのポイントがあります。初心者が以下に同じ回答を送信し、あなたが同意する場合は、それらを支持します。