インデックスを定義するときに列の特定の順序に利点がありますか


13

たとえば、2つのインデックスがある場合:

CREATE INDEX IDX_1 ON MY_TABLE_1
 (ITEM, DATE, LOCATION)
 COMPUTE STATISTICS;

CREATE INDEX IDX_2 ON MY_TABLE_1
 (DATE, LOCATION, ITEM)
 COMPUTE STATISTICS;

これはIDX_2冗長になりますか?そうでない場合、列を宣言する順序を決定するにはどうすればよいですか?

通常のクエリに合わせてインデックスを調整する必要がありますか?

回答:


12

はい、インデックスの一部に対してクエリを実行する場合に利点があります。部分的に使用される述語を最初に置くと、インデックス内のすべての列ではなく、それらの述語を含むクエリにインデックスを使用できます。

また、他の要件がない限り、最も選択的な述語を最初に置くと役立ちます。これにより、インデックスシーク操作をより迅速に削減できます。

あなたの場合IDX_2、テーブルのクエリの性質によっては必ずしも冗長ではありません。ただし、すべての列を含める必要はありません。たとえば、あなたがすることにより、クエリの多くを行う場合locationdate、その後IDX_2のようにこれらのクエリのヘルプ解決するために有用である可能性があるIDX_1ことのために有用であることが正しい順序ではありません。ただし、itemで重複している場合がありますIDX_2

Oracleは9iから、後続のインデックス列をより効率的に照会できる「スキップスキャン」演算子を導入しました。これにより、この種の補助インデックスの必要性を減らすことができます。

より具体的なケースでは、あなたが照会されている場合itemlocationかつdate、テーブルから何かを読まなく、クエリが完全にインデックスかかわらず解決することができ、他の列は必要ありません。インデックスのない列がアタッチされているカバーインデックスを作成することもできます。必要なすべての列がカバリングインデックスから解決できる場合、クエリはメインテーブルにまったく触れる必要はありません。

最後に、最後の質問への回答として:大量のリソースを消費し、インデックスを使用して調整できる、定期的に使用されるクエリのセットがある場合は、検討する価値があります。ただし、インデックスの維持には挿入のオーバーヘッドが伴うため、クエリのパフォーマンスとインデックスが挿入または更新操作にかけるオーバーヘッドとをトレードオフする必要があります。


3
@ConcernedOfTunbridgeWells:別の方法は、インデックスキー圧縮を使用し、選択性の低い(異なる値が少ない)列を先頭にすることです。スキップスキャンを適切に機能させながら、インデックスを小さくするのに役立ちます。
アダムマッシュ

2

考慮すべきもう1つのことは、多数のNULL値を持つ列です。

これらの列にインデックスで指定された列がある場合、null値にインデックスを付ける必要があります。それ以外の場合、通常どおり、null値はインデックス付けされません(もちろん、bツリーインデックスを使用していることを前提としています)。

したがって、多数のNULL値を持つ列がある場合、それらをインデックスの最後に配置すると、ディスク容量を大幅に節約できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.