web-dev-qa-db-ja.com

クエリプランが変更された理由を理解する

ERPシステムでパフォーマンスの問題が発生しました。06:00頃に問題が発生しました。長い話ですが、同僚の1人がDBCC FREEPROCCACHE(これは推奨されるアクションではないことを知っていますが、ここでは重要ではありません)。その後、彼はデータベースエンジンではなく、ERPアプリケーション全体を再起動しました。それは役に立たないようです。クエリストアを調べたところ、クエリプランが06あたりで変更されていることがわかりました。 05.古い計画を強制的に実行してみましたが、パフォーマンスの問題はなくなりました。

2つのプランXMLを比較したところ、どちらも同じ統計に基づいていることがわかりました(更新日はまったく同じでした)。インデックスの変更回数は異なりましたが、それ以外の場合、新しいクエリプランには使用された統計の新しい日付があったため、統計の更新はトリガーされませんでした。関連するテーブルのすべての統計をチェックしましたが、最後のメンテナンスジョブ以降は更新されていません。最後のメンテナンスジョブは今週末に実行されました。これは、両方のクエリプランで使用される統計の更新日でもありました。

クエリはパラメーター化されたクエリなので、クエリプランが突然変更された理由は少しわかりません。同じ計画が異なるパラメーターに使用されているため、クエリが突然遅くなるとは正反対だと思います。古いクエリプランを強制したため、これは当てはまりませんでした。

クエリは、注文を取得するオーダーメイドの作業からのものです。今、私は誰かが非常に大きなデータセットを返すパラメータ化されたクエリを発行し、それがERPシステムを遅くしました。そして、私の同僚がDBCC FREEPROCCACHEそして今週末の新しい統計に基づいて、クエリプランの再コンパイルをトリガーしました。現在のクエリは実行を継続し、ERPアプリケーションを再起動することにしました。新しいクエリプランでは、古いクエリプランを強制するまで、すべての新しいクエリの速度が低下しました。

これは説明でしょうか? SQL Serverは統計情報が変更されたときに再コンパイルをトリガーするので、私は少し懐疑的です。したがって、計画はインデックスメンテナンスジョブの後に既に再コンパイルされているはずです。

ここで何か不足していると思いますが、正確にはわかりません。これはSQL Server 2016 Standardであり、ERPシステムの専用サーバーです。

編集15-4-2020 12:17:これを書いたので...問題はDBCC FREEPROCCACHE問題のパラメーター化されたクエリの最初の実行のパラメーターが異なるパラメーターを使用していたため、SQL Serverは(不良)プランを再コンパイルしました。それとも私がまだ足りないものがありますか?

4
Niels Broertjes

統計はクエリオプティマイザーへの1つの入力ですが、唯一の入力ではありません。投稿で述べたように、オプティマイザはコンパイル時にパラメータ値も傍受し、それらを使用して、当時存在していた統計を使用して、フィルタ、結合、グループなどのさまざまな操作から得られる行数の推定値を生成しますコンパイル。さらに、ストレージエンジンはコンパイルごとに行カウントを提供し、これは統計を変更せずに変更することもできます(十分な行を変更すると、オプティマイザは最終的に統計を強制的に再計算します)。これらの変更のいずれかが、あるコンパイルから次のコンパイルに変更される計画の原因である可能性があります。クエリストアは、sys.context_settingsと呼ばれるテーブルを通じて、クエリが意味的に同じか異なるかを表すために内部的に使用する他の要素も実際に追跡します。したがって、ANSI NULLオン/オフは、結果に違いを引き起こす可能性のあるそのような意味上の変更の1つです。クエリストアはこれらを抽象化しますが、たとえば、ANSI NULLのオン/オフを変更するストアドプロシージャでループを作成し、ループ内で同じステートメントを繰り返し実行すると、実際にそれが得られます。 (sprocのその部分のステートメントが最後にコンパイルされたときから設定が変更されるたびに)何度もコンパイルします。これにより、実行ごとに新しいパラメーターをスニッフィングする機会も得られます。これらは技術的にはクエリストアで異なるクエリとして表示されますが、SQLエンジンにとっては、ストアドプロシージャのキャッシュされたクエリプランで同じステートメントスロットを保持しています。

SQL 2017+には、自動回帰と呼ばれる機能が含まれており、大規模なリグレッションに対して古い計画を自動的に強制できます。 Azure SQL DBにも同じ機能があります。将来的には、パラメータースニッフィングがお客様にとって問題にならないようにしたいと考えています。そのため、その間にシナリオの問題を回避するための洞察が得られることを願っています。