遅いクエリの調査中に、実行プランが非常に最適ではないように見えました(推定実行回数が1であるシークの900万回の実行をネストしたループ)。実際に古くなっているいくつかの関連する統計を確認したので、統計を再構築し、パフォーマンスの問題が効果的に解決されました。
このデータベースでは、統計の自動更新が有効になっています(デフォルトでオン)。20%+ 500行の変更(更新/挿入/削除)に基づく自動統計更新のしきい値があることを理解しています。このしきい値は、複数のインデックスで大幅に超えているようです。そのため、(A)自動更新に問題があるか、(B)オンラインで見つけた以上の更新方法があります。ドキュメンテーション。
統計を更新するようにスケジュールされたタスクを設定できることを感謝します。これは他の解決策が見つからない場合に採用するアプローチである可能性が高いですが、そのような大量の変更によってトリガーされない理由について混乱します一部の統計情報の自動更新-スケジュールされたタスクで更新する必要がある統計情報を判断するのに役立つ理由を理解する。
追加のメモ:
1)この問題は、負荷テストによってデータが作成されており、大量のデータが短時間で追加されるデータベースで指摘されたため、自動更新が定期的に(たとえば、1日に1回)発生した場合ほとんどの場合、これにより、観察された動作の一部が説明される場合があります。また、負荷テストはデータベースに大きな負荷をかける傾向があるため、負荷が高いときにSQLが統計の更新を延期しているのでしょうか(その後、何らかの理由で統計が更新されていません)。
2)連続するINSERT、SELECT、およびDELETEステートメントを含むテストスクリプトでこの問題を再現しようとすると、問題は発生しませんでした。ここでの違いは、これらのステートメントがそれぞれSQLステートメントごとの多くの行に影響を与えるのかどうか疑問に思っていますが、負荷テストスクリプトは行を個別に挿入する傾向があります。
3)問題のDBは、「単純」復旧モデルに設定されています。
いくつかの関連リンク:
私はマイクロソフトコネクトを介してこの問題を提起しました:
2011年6月30日更新:
さらなる調査では、しきい値レベル(たとえば、500行+ 20%)を超えて古くなっている統計は、問題のあるクエリで使用されていない統計であるため、クエリを実行すると更新される可能性がありますそれらを必要とします。クエリで使用される統計情報は、定期的に更新されています。残りの問題は、比較的少数の挿入(たとえば、推定数が1だった場合に前述の900万個程度のシークを引き起こす)の後で、これらの統計がクエリプランオプティマイザーに著しく誤解を与えることです。
この時点で私の問題は、問題は主キーの選択の不備に関連していることです。キーはNEWID()を使用して作成された一意の識別子であり、これにより非常に迅速にフラグメント化されたインデックスが作成されます-特にSQLのデフォルトのフィルファクターとしてサーバーは100%です。私の直感は、比較的少ない行の挿入後、どういうわけか統計の誤解を招く結果になり、統計を再計算するためのしきい値を下回ることです。インデックスを途中で再構築せずに大量のデータを生成したので、これはおそらく問題ではない可能性があります。したがって、不十分な統計は、結果として生じる非常に高いインデックスの断片化の結果である可能性があります。SQL Serverのメンテナンスサイクルを負荷テストに追加して、長期間にわたる実際のシステムのパフォーマンスをよりよく理解する必要があると思います。
更新2012-01-10:
考慮すべきもう1つの要素。SQL Server 2005に2つのトレースフラグが追加され(2008年にも引き続き存在するようです)、古い統計情報や誤解を招く統計情報の発生に関連する特定の欠点に対処します。問題のフラグは次のとおりです。
DBCC TRACEON(2389)
DBCC TRACEON(2390)
MSDN:Ian JoseのWebLog:昇順のキーと 昇順の列での自動クイック修正統計統計、Fabiano Amorim
これらのフラグが有害な影響を与える可能性があるため、これらのフラグを有効にすることを決定するときはもちろん、非常に注意する必要があります。