私たちのプロジェクトは、非常に大規模で非常に複雑なデータベースを実行しています。そのため、約1か月前に、null値を含むインデックス付き列で使用される領域が大きくなりすぎていることに気付きました。これに対する応答として、1%を超えるnull値を含むすべての単一列インデックスを動的に検索し、値がNOT NULLであるという条件でフィルター処理されたインデックスとしてそれらのインデックスを削除して再作成するスクリプトとして書きました。これにより、データベース全体で数百のインデックスが削除および再作成され、通常、DB全体で使用されるスペースのほぼ15%が解放されます。
今私はこれについて2つの質問があります:
A)この方法でフィルター処理されたインデックスを使用することの欠点は何ですか?パフォーマンスが向上するだけだと思いますが、パフォーマンス上のリスクはありますか?
B)インデックスを削除して再作成すると、「インデックスXYZは削除できないため、削除できません」というエラーが発生しました。後でチェックすると、すべてが期待どおりに実行されました。これはどうして起こりますか?
助けてくれてありがとう!
編集: @Thomas Kejserへの返信
こんにちは、ありがとうございます。しかし、これは災害でした。当時、私たちは次のようないくつかのことを理解していませんでした:
- SQLOSはクエリ中に、テーブル列の結合にNULL値を使用できないと判断する前に、インデックスプランを作成します。つまり、クエリで使用されるすべてのフィルター処理されたインデックスのインデックスをフィッティングするWHERE句フィルターが本当に必要です。そうしないと、インデックスはまったく使用されません。
- インデックスを削除して作成し、その後統計を冗長に更新するだけでは、更新された計画を作成するには不十分である可能性があります。場合によっては、SQL Serverが計画の再評価を余儀なくされるほど高いワークロードのみが表示されることがあります。
- 常識とロジックだけで判断するのが難しい実行プランナーの機能には、いくつかの珍しいものがあります。数千のコードビハインドで生成されたさまざまなクエリのバリエーションでさえ、一見役に立たないように見えるインデックスは、重要なクエリで使用される統計やクエリプランに役立ちます。
最終的に、これらの変更は元に戻されました。したがって、フィルター選択されたインデックスは強力なツールですが、これらの列からフェッチされるデータを正確に理解する必要があります。スペースの問題は別として、通常のインデックスは適用がかなり簡単ですが、フィルター選択されたインデックスは非常にカスタマイズされたソリューションを表します。これらは通常のインデックスの代わりではなく、必要な特別な状況での拡張です。