0

のテーブルがある場合TABLE_1、5列としましょう。

COL1    |   COL2    |   COL3    |   COL4    |   COL5
[line]
[line]
[...]

そして、私がやりたい主なクエリが2つあります。

SELECT * FROM table_a WHERE COL1 = 'X' and COL2 = 'Y'

そして他の存在:

SELECT * FROM table_a WHERE COL2 = 'Z'

どのインデックスを作成する必要がありますか?列を使用して1つを作成しCOL1、両方のクエリのインデックスを作成しますか、それとも2番目のクエリを高速化するためCOL2だけに別のインデックスが必要ですか?COL2

ありがとう!

4

3 に答える 3

5

上の通常の B ツリー インデックスはtable_a(COL2, COL1)、両方のクエリで使用できます。

この列にフィルターのみを使用して行を取得するには、インデックスをCOL2単独で持つ方が効率的かもしれませんが、追加のインデックスはスペースを使用し、挿入 (およびこの列を更新した場合は更新) が遅くなります。それはトレードオフです。

于 2011-07-29T09:22:10.487 に答える
4

彼の答えで、ヴィンセントはこう言っています:

「table_a(COL2, COL1) の通常の B ツリー インデックスは、両方のクエリで使用できます。」

その文の重要な単語は「could」です。そのようなインデックスがどちらのクエリでも使用されない可能性があることも事実だからです。

データベースのインデックス作成は、複雑で微妙なテーマです。このトピックについて書かれた本全体があります。Richard Foote は、何年もの間、Oracle Indexes (および David Bowie)だけについて話しているブログをなんとか維持してきまし

テーブルに関するいくつかの基本的な事実を知らずに、この質問に決定的な答えを出すことはできません。テーブルには何行ありますか? COL1 の異なる値はいくつありますか? COL2 の異なる値はいくつありますか?

それでは、いくつかの代替回答を見てみましょう。

TABLEA に 12 行しか含まれていない場合、フル テーブル スキャンがインデックス付き読み取りよりも効率的である可能性があります。

COL2 が一意の場合、必要な唯一のインデックスはtable_a(COL2)

COL2 が非選択的 (総行数と比較して比較的少ない値) の場合、2 番目のクエリでは、インデックス付き読み取りではなく、フル テーブル スキャンを使用する必要があります。

COL2 が非選択的であるが、COL1 が高度に選択的である (行の総数と比較して非常に多くの値が、一意ではない) 場合、最初のクエリは のインデックスを使用する必要がありますtable_a(COL2, COL1)

COL2 が特に選択的ではなく、COL1 も特に選択的ではないが、2 つの組み合わせが非常に選択的である場合、最初のクエリは のインデックスを使用する必要がありますtable_a(COL2, COL1)。フル テーブル スキャンは、2 番目のクエリの優先パスです。

COL1 が一意の場合、最初のクエリで使用されるインデックスが必要ですが、2 番目のクエリでは明らかに役に立ちません。

次に、問題をさらに複雑にする NULL の問題があります。複合インデックス (およびその他の特定の特殊なケース) を除き、NULL はインデックス化されません。

真に完全な回答は、スキューの問題にも対処します。COL1 の行の 90% が「0」で、残りが非常に選択的である場合、インデックスは役立つ場合とそうでない場合があります。インデックスを収集するときにヒストグラムを生成する必要があるかもしれませんが、クエリがバインド変数ではなくリテラルを使用する場合にのみ、ヒストグラムが本当に役立ちます。

于 2011-07-29T16:30:41.107 に答える
1

col2 と col1 で複合インデックスを使用することを検討できます。詳細については、Oracle コンセプト ガイドを参照してください。

于 2011-07-29T09:26:22.520 に答える