2012-12-09 23 views
11

長年の経験をDBAとして抱えていますが、私はその質問の答えを知っていると信じていますが、私は自分の根拠をチェックすることが決してないと思いました。第二のように、最初のインデックスを削除しても安全であるように、私はカラムAおよび列Bのインデックス、および第二列Aのインデックス、B、及びCを持つテーブルを持っていると仮定すると、SQL Serverの使用A、B、Cにインデックスがある場合、A、Bのインデックスは冗長ですか?

インデックスは基本的に最初のインデックスの恩恵を受けるクエリを満たすでしょうか?

+0

このトピックの詳細については、[Informixのグループインデックス](http://stackoverflow.com/questions/13858190/group-indexing-in-informix/13871985#13871985)を参照してください。 –

+0

免責事項では、この質問はノンクラスタード・インデックスについてのみ正しいですか?さもなければ、今後の読者は、クラスター化された索引Aを非クラスター化索引Bのほうにドロップすると、ズボンの中であなたを蹴ります。 – billinkc

+1

@billinkc - はい、クラスター化されていない索引のみです。クラスタ化インデックスは、データが物理的に順序付けされる方法に影響を与えます。クラスタ化されていないインデックスはその順序を使用する必要があるため、クラスタ化インデックスを削除または変更すると、それに依存する他のインデックスにも大きな影響があります。 – SchmitzIT

答えて

28

しかし、答えはしばしば「はい、インデックスを(A、B)にドロップすることができます」。

(A、B)のインデックスを削除しない場合のカウンタは、(A、B)のインデックスが制約を適用する一意のインデックスである場合です。索引を(A、B)にドロップしたくない場合。 (A、B、C)の索引も一意である可能性がありますが、(A、B)の組み合わせは他の索引のために一意であるため、一意性は冗長です。

しかし、(A、B)と(A、B、C)の両方が重複したエントリーを許可する場合など)は、(A、B)インデックスは論理的に冗長です。ただし、AとBが小さい場合(たとえばINTEGERの場合)、列Cが「ワイド」(おそらくCHAR(100)列)の場合、(A、B)索引はA、B、C )インデックスは、(A、B)インデックスのページごとに読み込まれる情報を増やすことができるためです。したがって、たとえ(A、B)が冗長であっても、それは価値があるかもしれません。また、テーブルのボラティリティも考慮する必要があります。テーブルがほとんど変更されない場合、余分なインデックスはあまり重要ではありません。テーブルが大きく変更された場合、余分なインデックスはテーブルの変更を遅らせます。それが重要かどうかは推測するのが難しいです。おそらくパフォーマンス測定を行う必要があります。

+2

+1ユニークなインデックスに注目してください。 –

+0

実際には、一意性ビットを追加するために+1します。私は例外があることを認識していますが、この場合は一般的な回答を探しています。 – SchmitzIT

11

最初のインデックスは、Aにルックアップクエリを覆うA,B及び第2のインデックスは、明らかに最初のケースのスーパーセットであるAA,B又はA,B,Cにルックアップクエリをカバーするために使用することができます。

Cが非常に広い場合、A,Bのインデックスは、読み取り回数が少ない特定のクエリを満たすことができるため、まだ有効です。

Cchar(800)列であった場合、次のクエリは、より狭いインデックスを利用できることから大幅に利益を得る可能性があります。

SELECT a,b 
FROM YourTable 
ORDER BY a,b 
+0

これは正確に私がそれを理解した方法です:) – SchmitzIT

7

はい、これは一般的な最適化です。 A、Bのインデックスから利益を得るクエリは、A、B、Cのインデックスからも同様に利益を得ることができます。 MySQLのコミュニティで

は、冗長インデックスのあなたの全体のスキーマを検索するためのツールでもあります:A、Bのインデックスは、よりコンパクトであり、はるかに頻繁に使用されている場合http://www.percona.com/doc/percona-toolkit/pt-duplicate-key-checker.html

可能例外ケースは次のようになり、そしてどのインデックスがメモリにロードされているかを制御したいと考えました。

+0

'A、B'は、より小さい恩恵を受けるレンジスキャンです。 – usr

+1

@usr:*両方の*インデックスを持つことは、 'A、B、C'インデックスだけを持つよりも確かに大きいです。 –

4

私が思っていたことの多くは、以前の答えでジョナサンによって書かれました。一意性、速い作業、そして私が彼が逃したと思うもう一つのこと。最初のインデックスは2番目の1は最初のもののスーパーセットではなく、クエリが恩恵を受けることができないので、彼は最初のインデックスは、本当に進むべき道ではありません、削除、A desc, B asc第二A asc, B asc, C ascがなされた場合に

順序付けが最初のものに書かれている場合は2番目の索引。いくつかのケースでは

あなたが最初のインデックスを使用するとき、あなたは(もちろん)order by A desc, B ascA asc, B descことができますが、またOrder by A descのように、そのインデックスのどの部分を使用するクエリを作ることができますように。

しかし、order by A asc, B ascのようなクエリは、最初のインデックスで「カバーされません」。

だから、通常は最初のインデックスを削除できますが、これはテーブルの構成とクエリ(もちろんインデックス)によって異なります。

+0

よく説明された新しい角度を思いついたことで恩恵を受けました:-) – SchmitzIT

2

私は通常、この履歴データを含むテーブルに "ほぼ"類似したインデックスを見つけるでしょう。 column Cが日付または整数列の場合は注意が必要です。これは、WHERE tblA.C = MAX(tblB.C)のようにMAX関数を満たすために使用される可能性が高く、テーブル全体をスキップしてインデックスのみのアクセスパスを使用します。

関連する問題