索引は表データへのアクセスの高速化するためのオブジェクト。表の目次。
通常B*Tree構造をしていて、表とは異なる領域に格納されている。データへの直接のアドレスを保持しているので、検索の速度は向上するが、データの挿入・更新・削除のたびに索引のメンテナンスが発生するので、速度の低下の可能性もある。必要最低限に絞るべき。
OEMホームページ>管理>スキーマ>索引
- PRIMARY KEYやUNIQEの制約をつけると、自動的に索引は作られる。それらの索引名は制約名と同じものがつけられる。
- 複数の列を結合した索引は作れるが、索引が使用されたり、されなかったりするので要注意。
- 索引データにはポインタが含まれていて、それを使ってダイレクトに行をアクセスする。ディスクのIOも減るので、アクセスが早くなる。結合につかっても早くなる。
- 索引がない場合、全表走査される。
- 表が更新されるたびに索引も更新されるので、更新の頻繁な表の場合、パフォーマンス劣化の原因にもなる。
- 対応する表から独立している。が、表に索引が作成されている場合は、表を削除すると索引も削除される。
- スキーマオブジェクトである。
- ORACLEサーバによって、自動的に使用・保守される。
- 非一意制約は重複を含むので、CREATE INDEXはUNIQEやPRYMARY KEYには使えない。
- 索引が自動的に制約によって作成される場合、索引名は制約の名前になる。
- OEM上の索引の作成の時(OEMホームページ>管理>スキーマ>表>索引の作成プルダウン)で、順序の項目で複数の索引を組み合わせて、作れる。
CREATE INDEX 索引名 ON 表名(列名[,列名]・・・) [TABLESPACE 表領域名]
CREATE INDEX 従業員名_INDEX ON 従業員(従業員名);
→従業員表の従業員列 をINDEXしたもので従業員名_INDEXという名前をつけた。
CREATE INDEX文は非一意索引も作成できる。
索引向きの列
- (大容量の)表の2~4%のデータを検索する場合。
- 列の値が一意である。
- WHERE句の条件として頻繁に利用される。
- NULLが多くて、NULL以外の値を検索する。
- カーディナリティが低い。カーディナリティは↓参照。
※カーディナリティとは、索引キーの値が行数に比べて少ない種類の値しか取らないことを意味します。例えば「性別」は「男」「女」の2種類の値のいずれかになりますが、これは最もカーディナリティの低いデータの例だといえます。
索引の活用
索引向きではない列
データの量の少ない表(そもそも索引をつけなくても、検索に時間がかからない)
列の値が頻繁に更新される。(索引も頻繁に更新されるので、効率が悪い)
WHERE句の条件としてあまりつかわない。(検索のキーにならないものの目次は必要ない)
SELECT句で頻繁につかわれる。(索引は検索対象を絞り込むためにつかうので、表示するためのSELECT句よりWHERE句で使われる行に定義した方がいい。)
WHERE句の条件として使用されるが、列が式の一部として参照される。
WHERE句・結合条件で1つ以上の列が一緒に頻繁に使用される。
表内の列の値の範囲が狭い場合。
索引の削除
DROP INDEX 索引名
PRIMARY KEYやUNIQE制約の自動的に作られる索引はDROP INDEXコマンドで消せない!
制約を削除か無効にすれば、それらの索引も削除される。
よくわからないこと
表領域の指定にUSING INDEX句を記述する。↓これらはどこで使う構文?
[CONSTRAINT 制約名] UNIQUE | PRIMARY KEY
[USING INDEX [TABLESPACE 表領域名]]
