時間の経過に伴う一貫したクエリパフォーマンス
かなりの量のデータを含むSQLServerデータベースに対して、集中的なアプリケーション負荷(数千の操作/秒)を実行しています。一部のテーブルには数十億の行があり、これらのいくつかには多くの挿入と更新があります。
DBのパフォーマンスは一般的にはまったく問題ありませんが、定期的にクエリのパフォーマンスの問題が発生します。以前は問題なく機能していたかなり単純なクエリは、突然10〜100倍の時間がかかる場合があります。
これは、テーブル/インデックス統計とクエリオプティマイザーに関連しているようです-ほとんどの場合、統計の更新で問題が修正されますが、統計の更新によって状況が悪化する場合もあります(統計の更新を再実行すると、通常は解決されます)最終的に問題)。
起こっているように見えるのは、オプティマイザーが一部のクエリに客観的に間違ったインデックスを使用することを決定したことです。何日も何週間も正しいものを使用した後、突然。
私の質問は:なぜこれが起こっているのか、そしてそれについて何ができるのか?
このデータベースは、基本的に同じ負荷、ほぼ同じクエリ、および同じ量の更新で何年も実行されています。クエリの99.995%については、入力に関係なく、時間の経過とともにさまざまなインデックス戦略を決定する理由はありません(実際、そうすると、クエリのパフォーマンスが完全に破壊されます)。
上に示したように、スケジュールに従って統計を自動的に更新すると、恐ろしい問題が発生することがよくあります。統計サンプルが歪んでいる場合(少なくとも5%の確率で発生しているように見えます)、私たちは苦痛の世界に陥ります。
統計ヒストグラムと密度が時間の経過とともに変化しないことをSQLServerに(特定のテーブルで)伝える方法はありますか?このテーブルに関連するクエリに対して同じクエリプランを引き続き使用してください。そうでない場合、統計の更新の予測可能な結果を時間の経過とともに保証するにはどうすればよいですか(上記の偏った統計の問題を回避する)?
ストアドプロシージャはありません。SQLは制御できるので、変更される可能性がありますが、コードがたくさんあるため、すべてのクエリを変更する必要がある場合(たとえば、追加の句を追加する場合)は残念です。
フォローアップの質問:パラメータスニッフィングはストアドプロシージャにのみ関連しているようですが、それは正しいですか?
回答
最初に、その統計情報か、それともパラメータスニッフィングがあなたを傷つけているかどうかを判断することをお勧めします。
上記に関係なく、このテーマに関するアーランドの記事を読むことをお勧めします。
それについて何をすべきかを言うのは難しいです。それが統計なのかスニッフィングなのかはわかりません。
しかし、おそらく追加するOPTIMIZE FOR
ことが「その」解決策になる可能性があります。RECOMPILE
実行ごとに計画生産ヒットを取得する必要がないため、より安価です。そしてそれはあなたに予測可能性を与えます。もちろん、これは、統計がそれほど異なる場合がないことを前提としているため、統計上の理由により、同じパラメーター入力で異なる計画が生成されます。
1つのクエリを特定してみてください。クエリの計画が1つまたは複数あるかどうかを確認します。OPTIMIZE FOR
および/またはでテストしRECOMPILE
ます。データベース規模での「グローバル」オプションの1つは、データベースのパラメータースニッフィングを無効にすることです。これは、オプティマイザが値の手がかりを持たないため、最適化することを意味します。アーランドの記事にこれ以上のものがあります。
パラメータスニッフィングは、ストアドプロシージャだけに適用されるわけではありません。また、パラメータ化されたSQL(通常はを使用して実行されるsp_executesql
)にも適用されます。これは、今日ではストアドプロシージャよりもはるかに一般的です。
コメントから生成された回答
統計の更新後に取得した統計が間違っているため、間違ったクエリプランを取得する可能性があります。ただし、統計を更新した後、クエリが取得した最初のパラメータが通常とは異なる場合、パラメータがスニッフィングするため、間違ったクエリプランを取得する可能性もあります。あなたの質問から、どの問題が提示されているかを理解することは不可能です。統計を更新して2つの異なる問題を分割するのではなく、クエリが悪化したときにクエリプランを再コンパイルしてみてください。–デニス・ルバシュキン
実行プランの「再構築」を引き起こす可能性のある多くの要因があります。それで、それはなぜそれがしばらくの間うまく働き、突然遅く働き始めるのかを説明するでしょう。統計を更新すると、このオブジェクトに関係するすべての実行プランが無効になり、次の実行で新しいプランが作成されます。使用する値に応じて、問題が修正される場合とされない場合があります(ほとんどの値は修正されますが、他の値は修正されません。これにより、機能する場合と機能しない場合があります)。
実行プランを「修正」するもう1つの方法は、クエリストア(SQL Server 2016から始まったと思います)を使用して、使用するプランを「修正」することです。データが大幅に変更されると(SQL Serverはより良いプランを作成できないため)、いくつかの欠点がありますが、そのような問題は修正できます(2年前から修正実行プランでクエリを実行していて、それ以来、パラメータスニッフィングの問題はありません)。–ドミニクブーシェー