統計、実行計画、および「昇順の主要な問題」を理解する


11

統計、実行計画、ストアドプロシージャの実行の間の関係を(概念的に)よりよく理解しようとしています。

統計はストアドプロシージャの実行プランを作成するときにのみ使用され、実際の実行コンテキストでは使用されないというのは正しいことですか?つまり、これが当てはまる場合、プランが作成されたら(そしてプランが適切に再利用されていると仮定して)、「最新の」統計はどのくらい重要ですか?

特に私が読んだ記事(統計、行の見積もり、昇順の日付の列)は、クライアントのデータベースのいくつかで毎日直面しているシナリオと非常によく似たシナリオを説明しています。

特定のストアドプロシージャを使用して定期的にクエリする最大のテーブルの1つに昇順の日付/時刻列があります。

1日に10万行が追加されるときに、実行プランが古くならないようにするにはどうすればよいですか。

この問題に対処するために統計を頻繁に更新する場合、このストアドプロシージャのクエリでOPTION(RECOMPILE)ヒントを使用することは理にかなっていますか?

アドバイスや推奨事項をいただければ幸いです。

更新:SQL Server 2012(SP1)を使用しています。

回答:


5

統計はストアドプロシージャの実行プランを作成するときにのみ使用され、実際の実行コンテキストでは使用されないというのは正しいことですか?

いいえ、ストアドプロシージャの実行プランがキャッシュされるということです。プランを保持し続けるのに十分なメモリがあると仮定すると、次のいずれかが発生しない限り、メモリは変更されません(SQL Serverドキュメントの実行プランのキャッシュと再利用から、強調が追加されています)。

  • クエリによって参照されるテーブルまたはビューに加えられた変更(ALTER TABLEおよびALTER VIEW)。
  • キャッシュからそのプロシージャのすべてのプランを削除する単一のプロシージャに加えられた変更(ALTER PROCEDURE)。
  • 実行プランで使用されるインデックスの変更。
  • UPDATE STATISTICSなどのステートメントから明示的に生成された、または自動的に生成された、実行プランで使用される統計の更新。
  • 実行プランで使用されているインデックスを削除する。
  • sp_recompileへの明示的な呼び出し。
  • キーに対する多数の変更(クエリによって参照されるテーブルを変更する他のユーザーからのINSERTまたはDELETEステートメントによって生成される)。
  • トリガーのあるテーブルで、挿入または削除されたテーブルの行数が大幅に増加した場合。
  • WITH RECOMPILEオプションを使用してストアドプロシージャを実行する。

したがって、統計が更新されると、キャッシュされたプランは自動的に新しい統計を考慮に入れて再コンパイルされます。

1日に10万行が追加されるときに、実行プランが古くならないようにするにはどうすればよいですか。

1つの方法は、上記のように、テーブルに多くの更新がある場合です。数十万の変更された行がこの条件を満たす場合があります。しかし、確実にしたい場合や、より詳細に制御したい場合は、統計を更新します。SQL Serverに統計の自動作成と管理を許可するか、手動で統計を作成できます。どちらの方法についても、SQL Server Auto UpdateおよびAuto Create Statistics Optionsで詳細を確認できます。毎週インデックスを再構築する場合、または再構築すると、プランも更新されるようになります。統計を頻繁に更新すると実際のパフォーマンス結果が得られない可能性があるため、いくつかのテストを行って、何が最も有益かを確認してください。

この問題に対処するために統計を頻繁に更新する場合、このストアドプロシージャのクエリでOPTION(RECOMPILE)ヒントを使用することは理にかなっていますか?

上記の抜粋に基づいて、新しい統計が利用可能になるたびに実行プランが適切に更新されることがわかるので、を使用する必要ありませんRECOMPILE。1日の終わりの統計の更新で大丈夫かもしれません(本当に心配している場合)が、これまでに言ったことに基づいて、それが明示的に必要であるとは思わない。繰り返しますが、これをテストして、ストアドプロシージャのパフォーマンスに与える影響を確認し、それに応じて計画を立てます。


RECOMPILEとにかく統計の更新を引き起こしません。
マーティンスミス

@MartinSmith正解です!わかりやすくするために編集します。
LowlyDBA 2015年

@LowlyDBA次のトピックを参照してください。dba.stackexchange.com/questions/207475/...
lukaszwinski

6

統計は実行計画を作成するときにのみ使用されると言っても正しいですか

いいえ、統計が古くなっていると、影響を受けるステートメントの最適性関連の再コンパイルが発生する可能があります。

定期的にクエリする最大のテーブルの1つに昇順の日付/時刻列があります

述語値が対応する統計ヒストグラムに格納されている値の範囲外(具体的には上)にあるために発生する準最適な実行プランは、昇順キー問題と呼ばれます。統計の再構築は1つの可能な解決策ですが、かなりのリソースを消費する可能性があります。代替案は次のとおりです。

  • トレースフラグ2389および2390。これには、問題のある列を主キーとするインデックスが存在する必要があります。パーティションテーブルでは機能せず、元のカーディナリティエスティメータが使用されている場合、SQL Server 2014でのみ有効です。統計オブジェクトが静止している場合は、トレースフラグ4139も必要になることがあります。

  • SQL Server 2014にアップグレードします。新しいカーディナリティエスティメータには、平均密度情報を使用してヒストグラムを超えて推定するロジックが含まれています。これは、一部の重要な状況では、2389/2390トレースフラグよりも正確ではない可能性があります。

  • トレースフラグが2371の大きなテーブルに対して、より頻繁な自動統計更新を有効にします。20%+ 500、変更後のこのトレースフラグの代わりに更新して、唯一のSQRT(1000 * Table rows)修飾が必要です。更新がまだ十分に頻繁にトリガーされない可能性があるため、これは前述のソリューションほど完全なソリューションではありません。

問題の原因が、ヒストグラムを超えた述語値に基づくそれほど頻繁なプランのコンパイルではなく、パラメーターのスニッフィングの結果として、このような悪いプランを時々キャッシュすることの影響についての詳細は、次のことも検討できます。

  • トレースフラグ4136を使用したパラメータースニッフィングの無効化
  • を使用OPTIMIZE FOR (@parameter = value)して既知の代表値の計画をコンパイルする
  • OPTIMIZE FOR (@parameter UNKNOWN)平均分布を使用して最適化するために使用
  • 使用OPTIMIZE FOR UNKNOWN(4136と同じ、ただしクエリごと)
  • を使用OPTION (RECOMPILE)して毎回コンパイルし、特定の値をスニッフィングします。ランタイム値の大部分がヒストグラム内にある場合、これは効果的です。

パラメータのスニッフィング、埋め込み、および再コンパイルオプションの詳細については SQLperformance.comの私の記事を参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.