データウェアハウスから毎日スケジュールされたジョブを使用してロードされるクライアントに関する情報を格納するテーブルがあります。そのテーブルには 100 万を超えるレコードがあります。値の数が限られているため、Country 列に BitMap インデックスを定義したかったのです。データを毎日削除してテーブルに再ロードすると、インデックスに影響がありますか。読み込みのたびに明示的にインデックスを再構築する必要がありますか?
4 に答える
表が頻繁に更新される場合(索引付けされた列)、ビットマップ索引は危険です。これは、単一行のDMLが表内の多数の行をロックする可能性があるためです。これが、OLTP よりもデータ ウェアハウス ツールである理由です。また、ビットマップ インデックスの真の力は、論理演算を使用してより多くのインデックスを結合し、結果を ROWID に変換する (そして、行にアクセスするか、それらを集計する) ことで発揮されます。Oracle では一般に、インデックスを再構築する理由はそれほど多くありません。頻繁に変更されると、常に 50/50 のブロック分割によって適応されます。可能な限り小さなスペースにコンパクトにしようとしても意味がありません。各行に大量のデータが含まれていない限り、今日の 100 万行は意味がありません。
また、BITMAP インデックスには Enterprise エディションのライセンスが必要なことにも注意してください。
値の数が限られているため、Country 列に BitMap インデックスを定義したかったのです。
列のカーディナリティが低いからといって、ビットマップ インデックスの候補になるわけではありません。そうかもしれないし、そうじゃないかもしれない。
ここでTom Kyteによる良い説明。
ビットマップ インデックスは、多数のアドホック クエリがある環境、特にアドホックな方法で多くの列を参照するクエリや、COUNT などの集計を生成するクエリがある環境で非常に役立ちます。たとえば、GENDER、LOCATION、AGE_GROUP の 3 つの列を持つ大きなテーブルがあるとします。この表では、GENDER は M または F の値を持ち、LOCATION は 1 から 50 の値を取ることができ、AGE_GROUP は 18 歳以下、19 歳から 25 歳、26 歳から 30 歳、31 歳から 40 歳、41 歳以上を表すコードです。
例えば、
次の形式をとる多数のアドホック クエリをサポートする必要があります。
select count(*)
from T
where gender = 'M'
and location in ( 1, 10, 30 )
and age_group = '41 and over';
select *
from t
where ( ( gender = 'M' and location = 20 )
or ( gender = 'F' and location = 22 ))
and age_group = '18 and under';
select count(*) from t where location in (11,20,30);
select count(*) from t where age_group = '41 and over' and gender = 'F';
従来のB*Tree
索引付け方式ではうまくいかないことに気付くでしょう。B*Tree
インデックスを使用して答えを得る場合、インデックスを介してデータにアクセスするには、可能なインデックスの組み合わせが少なくとも 3 つ、最大 6 つ必要になります。3 つの列のいずれか、または 3 つの列のサブセットが表示される可能性があるため、大規模な連結 B*Tree インデックスが必要になります。
- GENDER、LOCATION、AGE_GROUP: 3 つすべてを使用したクエリ、または GENDER と LOCATION を使用したクエリ、または GENDER のみを使用したクエリの場合
- LOCATION、AGE_GROUP: LOCATION と AGE_GROUP、または LOCATION のみを使用したクエリの場合
- AGE_GROUP、GENDER: AGE_GROUP と GENDER を使用したクエリ、または AGE_GROUP のみを使用したクエリの場合
ビットマップ インデックスを定義する理由は、列内のいくつかの値ではなく、テーブルの行にアクセスすることで利益を得ることができるクエリです。
たとえば、4 つの国の人口が均等であると言う場合、FULL TABLE SCAN の方が安価になるため、Oracle はインデックスを使用しません。
いくつかの「エキゾチックな」国 (レコードが非常に少ない) がある場合は、BITMAP インデックスを使用できますが、通常のインデックスとの違いはおそらく見当たらないでしょう。
テーブルにビットマップ インデックスを 1 つしか持たないことは、ほとんどの場合役に立ちません。1 つのテーブルに複数のインデックスを作成し、クエリでそれらを組み合わせると、ビットマップ インデックスの利点が得られます。
あなたの場合、リストパーティションの方が適しているかもしれません。