web-dev-qa-db-ja.com

不等式クエリのインデックスを作成するにはどうすればよいですか?

Float列の値に基づいてデータを除外するクエリがあります

select * 
from My_Table
where my_Float_column != 0 and my_Float_column is not null

私がそれを助けることができるならば、私はフロートタイプにインデックスを付けたくありません。実行プランは、パフォーマンスを向上させるために、以下のようなフィルターされたインデックス(ここでは0とnull値のみをインデックス付けする)を使用するのに十分賢いでしょうか?

CREATE NONCLUSTERED INDEX IX_My_Table_Float_Filtered
    ON My_Table (my_Float_column)
    WHERE my_Float_column = 0 or my_Float_column is null
10
Neil P

実行プランは、パフォーマンスを向上させるために、以下のようなフィルターされたインデックス(0とnull値のみをインデックス付けする)を使用するのに十分賢いでしょうか?

いいえ。SQLServerでは、考えているように見える単一演算子の行の拒否を直接サポートしていません。

より一般的に言えば、フィルターされたインデックスは、特定のクエリに直接役立つわけではなく、いずれにしても有効なインデックスフィルター定義ではありません。代わりにこれらの述語を含むインデックス付きビューを作成することもできますが、それでもターゲットクエリの行を見つける方法としては役に立ちません。インデックス付きビューを使用して別のフルスキャンでフェッチされた行を除外するようにクエリを書き直すこともできますが、それが一般的にどのように優れているかを理解するのは困難です。

取得できる最も近いのは、ビットマップフィルターを設定するインデックス付きビューのスキャンであり、そのフィルターはターゲットテーブルのフルスキャンの一部として適用されます。このクエリプランの形状を確実に取得することは困難な場合があります。

CASE式を使用してインデックス付きの永続計算列を使用することもできますが、これも元のクエリを書き換える必要があり、テーブルのすべての行とインデックスにストレージが必要になります。

与えられた情報から、あなたができる最善のことはインデックスを次のように定義することです:

CREATE NONCLUSTERED INDEX IX_dbo_My_Table__Float_Filtered
ON dbo.My_Table (my_Float_column)
WHERE 
    my_Float_column <> 0 
    AND my_Float_column IS NOT NULL;
11
Paul White 9