2009-10-11 1 views
11

次の2つのインデックスに違いはありますか?2つのインデックス間の差が、逆順で定義された列の場合

  • IDX_IndexTables_1
  • IDX_IndexTables_2

いずれかがある場合は、違いは何ですか?

create table IndexTables (
    id int identity(1, 1) primary key, 
    val1 nvarchar(100), 
    val2 nvarchar(100), 
) 

create index IDX_IndexTables_1 on IndexTables (val1, val2) 
GO 

create index IDX_IndexTables_2 on IndexTables (val2, val1) 
GO 

答えて

16

はい。違いがあります。

複合インデックスIDX_IndexTables_1は、val1カラムがwhere句で使用されているすべてのクエリに使用できます。

複合インデックスIDX_IndexTables_2は、val2列がwhere句で使用されているすべてのクエリに使用できます。

ので、例えばIDX_IndexTables_2は、このクエリに使用することはできません(ただし、IDX_IndexTables_1を使用することができます):

SELECT val1, val2 FROM IndexTables 
WHERE val1 = some_value 

が、このクエリのために使用することができます。

SELECT val1, val2 FROM IndexTables 
WHERE val2 = some_value AND val1 = some_other-value 

について考えるための方法複合インデックスは紙の電話帳について考える。これは、姓の列、そしてfirstnameの列によって索引付けされます。姓で検索できますが、firstnameで検索することはできません。

+0

コンポジットインデックスのアナロジーは、その違いを簡単に理解するのに役立ちました。ありがとう、ミッチ。 – Sung

+0

本当に素晴らしい答えです。 +1 – spender

2

あなたが持っているものは複合インデックスです。 WHERE句がコンポジット索引のすべての列を使用していない場合は、順序が重要です。あなたの複合インデックスの列を左から右へ読んで考えられるかもしれないものをインデックス知るために

SELECT val1 
FROM IndexTables 
WHERE val1 = 'MyValue' 

は、このクエリを考えてみましょう。クエリのすべての列を読み取る前に列がクエリに存在しない場合、インデックスは使用されません。

IDX_IndexTables_1(val1とは、VAL2):右val2の左から読むことはしません。したがって、このインデックスは

IDX_IndexTables_2(val2の、VAL1)と考えられる右val1と左から読むことが存在し、それが私たちの唯一の列でありますこのクエリには存在しないので、使用されません。

4

マルチカラムインデックスは概念的には、すべてのカラムフィールドを取り込み、それらをまとめてconcatenationすることと同じです。結果を単一のフィールドとして索引付けします。

インデックスはbツリーであるため、常に左から右に検索されます。左から検索を開始して、結果が正しいかどうかを検索して、インデックスがその仕事をして有用な結果をもたらすようにする必要があります。同じ概念は、マルチカラム・インデックスに適用される

WHERE val1 LIKE 'myvalue%' (uses index) 
WHERE val1 LIKE '%myvalue' (cannot use index) 

順序はVAL1は、VAL2

WHERE val1='value1' (uses index) 
WHERE val2='value2' (cannot use index) 

は順序がVAL2で索引付けのみ単一のフィールドと

、val1

WHERE val1='value1' (cannot use index) 
WHERE val2='value2' (uses index) 

両方のフィールドが一致している場合、インデックスの順序は重要ではありません。

WHERE val1='value1' AND val2='value2' (uses index in any order) 
2

上記の回答は、各インデックスの最初の列の使用方法を説明しています。 (where句内)。

2番目の列を含むクエリのパフォーマンスが潜在的に向上するため、2番目の列が有用であると指摘することも重要です。

次のクエリは、IDX_1でインデックスをシークするだけで済むので、val2は既にインデックスの一部であるため、基本テーブルに貴重な検索を保存します。

SELECT val2 from IndexTables where val1 = @someVal1 

同様に、逆にインデックスがこのクエリを最適化します:

SELECT val1 from IndexTables where val2 = @someVal2 

しかし、一つだけ(それはどの問題ではありません)2つの指数のは、次のクエリを最適化する必要がある。

SELECT val1, val2 from IndexTables where val1 = @someVal1 and val2 = @someVal2 

これは、テーブルが受け取るクエリによっては、両方のインデックスを持つ正当な理由がある可能性があることを示しています。

+0

インデックスが一意でない場合、1つのコンポジットは、ディストリビューションに応じて、他のコンポジットよりも選択性が高い場合があることに注意してください。しかし、それはおそらくマイクロ最適化です... –

+0

良い点マイク。より大きなスケールでは、これは「ミクロ」最適化ではないかもしれません。 –

1

他の民間人は、彼らは異なっていると答えており、私は同意します。私もいくつかの他の思考追加します

...(COL1、COL2)インデックスはあなただけではCOL1

  • (COL2、COL1)インデックス手段上のインデックスを必要としないことを意味
    • これはカバーされている場合は、COL2だけで
    • 順序が重要にインデックスを必要としない(例えばWHERE col1の上、SELECT COL2)
    • 方向(ASC/DESC)も重要(Other question 1Other question 2
  • +0

    +1 "方向(ASC/DESC)も重要です"良い点!ありがとう。 – Sung

    +0

    あなたは(col1、col2)を持っているなら、あなたは単にcol2、col1の代わりに(col2)を持つことができますか? – Renae

    +0

    @Renae:多分、これは例えばです。 – gbn

    関連する問題