こんにちは。キャスレーコンサルティング SI部の秋葉です。

今回は、RDBMSの索引(Index)について記載していきます。

索引は検索のパフォーマンスを向上させる目的で使用されます。

DBの索引は、書籍での索引のようなイメージです。
書籍のページ数が多く、その一部分を読みたいは索引があるとすぐに読めるように、
DBも全体のデータ件数が多く、一部のデータを検索する場合に索引があると速く検索できます。

索引を作成すべき例について、以下にまとめてみました。

●一般的に、索引を作成すべき列の特徴は下記のようになります。

①テーブル内のデータ量が多く、少量のレコードを検索する場合

全体の2~4%未満であることを判断基準としていいようですが、データ量や条件に左右されため、
抽出する量の15%程度でも実際に流して試してみるのがいいかと思います。

また、テーブル内のレコード件数によっては、索引がないほうが早い場合があります。
インデックススキャンは、1ブロックずつ読み込むが、フルスキャンは数ブロック単位で読みこむためです。
※ちなみに読み込むブロック数は初期化パラメータ「db_file_multiblock_read_count」で変更できます。
※また、問合せに必要なすべての列が索引に含まれている、若しくは結果にNULL値がない場合は、
高速全索引スキャンにより数ブロック単位で読み込まれます。

②カーディナリティが高い(列の値の種類が多い)
例えば区分などの場合で、0又は1の値しか持っていない場合は、
索引の種類がBツリーインデックスの場合は効果はあまり得られません。

Bツリーインデックスは、ルート→ブランチ(n)→リーフ(n)といった構造のOracleデフォルトの索引で、
値の種類が多い(カーディナリティが高い)列に有効なインデックスです。
※Index作成時にBITMAP指定し、BITMAP索引にした場合は、値の種類が少ないほうが早くなります。

③WHERE句の条件、または結合の条件として頻繁に使用する。
WHERE句に条件を指定する検索が中心となる表には索引が必要となります。
全表走査が目的のテーブルであれば、索引は不要です。

④NULL値が多く、NULL値以外の検索をする
Indexは、NULL値を含みません。
そのため、Null値以外の値の検索には効果があります。

●逆に索引を作成すべきでない列の特徴が下記のものです。

①表の規模が小さいか、表から大部分のレコードを検索する場合に使用する。

②WHERE句の条件としてあまり使用されないもの。

③列の値が頻繁に更新される。
索引は、表からは独立した存在です。
表に新規行が挿入されれば、索引にも自動的に値が格納されます。

そのため、索引を作成するとデータ検索の速度は向上しますが、
データの挿入、更新、削除の処理では索引のメンテナンス作業が発生し、速度の低下につながります。

索引更新の負荷も考慮し、Indexを作りすぎないようにしましょう。

④WHERE句の条件として使用されるが、列が式の一部として参照される。
下記のwhere句のような計算式を入れたりすると、索引が使われません。

sql①

索引の作成

索引の作成には、CREATE INDEX文を使用します。

sql②

また、プライマリキー制約やユニークキー制約を定義した際には、自動的に一意索引が作成されます。

索引の削除

sql③

また、表を削除すると、索引、制約は自動的に削除されます。