1

インデックスウィザードがさまざまなシナリオに対して提案した方法に基づいて、これら2つのインデックスを作成しました。同じなのか違うのかしら?

インデックス(1):

CREATE NONClustered Index [IX_Rec_RecoveryDate_RecoveryDateTypeKey_CaseId] 
ON [Rec].[RecoveryDate] ([RecoveryDateTypeKey], [CurrentFlag])
INCLUDE (CaseId)

インデックス(2):

CREATE NONClustered Index [IX_Rec_RecoveryDate_currentFlag] 
ON [Rec].[RecoveryDate] ([CurrentFlag])
INCLUDE (CaseId, RecoveryDateTypekey)
4

3 に答える 3

4

問題は、どのクエリを最適化しようとしているのかということです。

これらの2つのインデックスは大きく異なります。最初のインデックスは、次のようなクエリに最適です。

SELECT CaseId 
FROM Rec.RecoveryDate
WHERE RecoveryTypeKey = 5
AND CurrentFlag = 1 -- or whatever

最初のものは、WHERE句の列にインデックスを付けます。SQL Serverは、指定されたRecoveryDateTypeKeyとCurrentFlagを検索できます。CaseIdはインデックスリーフノードに含まれているため、SQLServerはそれを取得するためにテーブルに結合し直す必要はありません。

同じクエリを使用すると、2番目のインデックスの動作が異なります。運が良ければ、SQL ServerはCurrentFlagが1であるすべてのレコードを検索します。次に、これらのリーフノードをトラバースして、一致するRecoveryTypeKeyを探します。一方、CurrentFlagが1であるレコードが多数ある場合、SQLServerは代わりにインデックススキャンを実行することを選択する場合があります。

次に、次のようなクエリを最適化する場合は、次のようにします。

SELECT CaseId, RecoveryTypeKey
FROM Rec.RecoveryDate
WHERE CurrentFlag = 1

CurrentFlagはインデックスの2番目の列であるため、最初のインデックスは役に立ちません。SQLServerはCurrentFlag=1を検索できないため、おそらくインデックススキャンを実行します。

于 2012-12-04T22:23:22.360 に答える
2

それらは異なります。インデックス1は2つの列にインデックスを付け、インデックス2は1つの列にインデックスを付けますが、ノードには2つの列が含まれます。

違いは基本的に、2つの列を使用して検索する場合、インデックス1はインデックス2よりもはるかに高速である可能性があることを意味し
ます。結果にもう一方の列が必要な場合はインデックス2であるため、インデックス2は一方の列の通常のインデックスよりも優れています。すでに値を持っているので、実際のテーブルでのルックアップは必要ありません。

于 2012-12-04T22:11:00.497 に答える
0

インデックスは同じ情報(caseid、RecoveryDateTypeKey、CurrentFlag列を持つRecoveryテーブルの行ごとに1行)を格納しますが、異なる順序で編成されているため、異なるクエリに使用できます。

最初のインデックスは、次のようなwhere句を処理できます。

WHERE RecoveryDateTypeKey = @p1 --Prefix matching!

WHERE RecoveryDateTypeKey = @p1 AND CurrentFlag = @p2

2番目のインデックスは処理のみ

WHERE CurrentFlag = @p2

CurrentFlagがビットやchar(1)(Y / N)などの低カーディナリティ列である場合は、フィルター処理されたインデックスをお勧めします。

CREATE INDEX IX_REC_Yes_fltr on Recovery (RecoveryDateTypeKey) WHERE (CurrentFlag = 'Y')
INCLUDE (CaseId) --Assumes that CurrentFlag = 'Y' is the most used value

--Maybe even a second one.
CREATE INDEX IX_REC_No_fltr on Recovery (RecoveryDateTypeKey) WHERE (CurrentFlag = 'N')
INCLUDE (CaseId) --Maybe handle CurrentFlag = 'N' as well.

フィルタリングされた各インデックスには、基準を満たす値のみが含まれるため、それらを組み合わせると、フィルタリングされていないインデックスと同じサイズになります。

于 2012-12-05T05:42:47.407 に答える