アプリケーションデータベース(SQL Server 2016エンタープライズ、最大500 GBのデータ)で「不良」データを検索するストアドプロシージャがあります。ビジネス/プロセスの意味で「悪い」。
通常、実行には10〜30秒かかります。数日後、実行に突然5分以上かかります。
私の現在の解決策は、すべての統計を再計算することであり、実行時間は再び短くなります。
EXECUTE dbo.IndexOptimize @Databases = 'myDB',
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y'
明らかに、統計を再生成することは、新しくより良いクエリプランにつながります。遅いクエリプランを導入する誤解を招く統計を特定するための的を絞った方法はありますか?または、どうすればこれの原因を見つけることができますか?テーブル、インデックス、統計、およびこのストアドプロシージャは複雑であるため、推測できません。更新の「前」と「後」の統計をプログラムで比較できますか?
通常は非常に小さいフィルタリングされたインデックスが多数あるため、20%のルールが頻繁に適用される場合があります。
インデックスは毎週最適化されます。
2016 SP2/2017では、実際の計画を生成できます。 使用された統計が表示されます 。古いバージョンでは、同じことを行うことができますが、トレースフラグを使用します Paul Whiteがここで説明しているように 。しかし、あなたが正しいと思います。統計を更新すると新しい計画がトリガーされますが、統計を更新することは、より良い計画につながるものではなく、統計の更新後に初めて生成される新しい計画にすぎません。そもそもなぜ計画がうまくいかないのかを理解する必要があります。
これは検索プロシージャであるとおっしゃっていますので、これはパラメータの感度の問題であると推測します(プロシージャの定義といくつかの一般的な呼び出しを確認すると確認に役立ちます)。ここには2つの考えがあります。
WHERE
句を使用してのみクエリを作成します。これにより、SQL Serverは、パラメーターの一意の組み合わせごとに異なる方法で最適化できます(インスタンスレベルの_optimize for ad hoc workloads
_設定と組み合わせることを強くお勧めします)。OPTION (RECOMPILE)
を検討してください。これにより、SQL Serverは毎回パラメーターを再検査し、行数に基づいて最適化する必要がありますthisパラメーターのセットが生成する可能性があります。再コンパイルにはいくらかのオーバーヘッドがありますが、それがもたらす安定性のためにそれだけの価値があることがよくあります。1と2の両方が時々真である場合は、組み合わせを検討してください-ステートメントを動的に構築しますおよび最後にOPTION (RECOMPILE)
を追加します。
私はここでこれについてもっと深く話します:
確かに、最新の統計は役に立ちますが、統計が更新された後にコンパイルされる最初のプランを単に再利用する場合、それらは価値がありません。初めて「S%」のような姓を検索し、2回目に給与<70000を検索する場合、2回目は間違ったインデックスを使用します。フィルタリングされたインデックスについては、そうです。20%のしきい値(またはTF2371を模倣する新しいインデックス)に陥る可能性は低いため、手動で更新したままにしておくことをお勧めします。ただし、少なくとも動的SQLを使用する場合は、適切な場合にのみ、フィルター処理されたインデックスプランを使用する機会があります。
他のいくつかの読書: