4

実稼働環境にテーブルがあり、テーブルに 2 つのインデックスがあり、インデックスに同じ列がありますが、順序が逆になっています。

DDLは

 - CREATE INDEX IND_1 ON ORDERS (STORE_ID,DIST_ID)  
 - CREATE INDEX IND_DL_1 ON ORDERS (DIST_ID,STORE_ID)

これら 2 つのインデックスは本質的に同じではありませんか。なぜ誰かがそのような方法でインデックスを作成するのでしょうか? 列の位置を反転または変更すると、内部的に何かが行われますか?

4

2 に答える 2

5

インデックスは、インデックスで定義されている順序で、インデックスを作成しているフィールドに関連付けられています。インデックス内のフィールドを左から右の順序で使用する限り、インデックスはクエリに使用できます。フィールドをスキップしている場合、インデックスは使用できません。たとえば、次のインデックスが与えられた場合:

CREATE INDEX ind1 ON foo (bar, baz, qux)

次に、これらの where 句でインデックスを使用できるようになります。

WHERE bar=1
WHERE bar=1 AND baz=2
WHERE baz=2 AND bar=1  <--same as before
WHERE bar=1 AND baz=2 AND qux=3

クエリでインデックス付きフィールドを使用する順序は関係ありません。それらを使用しているだけです。ただし、インデックスで定義されている順序は重要です。次の句では、インデックスを使用できません。

WHERE baz=2  <-- 'bar' not being used
WHERE baz=2 AND qux=3  <-- 'bar' again not being used
WHERE bar=1 AND qux=3  <-- the index can be partially used to find `bar`, but not qux.

あなたの 2 つのケースでは、インデックスの作成方法に問題はありませんが、次のようにインデックスを作成する方が少し効率的です。

(STORE_ID, DIST_ID)
(DIST_ID)

DBMS は最初のインデックスを使用して store_id ルックアップを処理できるため、2 番目のインデックスで store_id のインデックスを作成しても意味がありません。これは大きな利点ではありませんが、それでも... インデックスを維持することは DB のオーバーヘッドであり、オーバーヘッドを削減することは常に良いことです。

于 2013-08-22T19:14:29.450 に答える
1

必要な情報がすべてインデックスにある場合、Oracle はテーブル セグメントにアクセスする必要はありません。あなたの場合、これらのインデックスはクイックルックアップ/変換テーブル STORE_ID => DIST_ID として機能し、その逆も同様です。

DIST_ID に基づいて STORE_ID のみを選択するクエリの実行計画を見てください。クエリはインデックスのみを通過し、テーブル自体には触れません。

しかし、おそらく理由は異なります(もしあれば)。

于 2013-08-23T07:02:35.700 に答える