FE EXAM

インデックス(索引)

列の値と格納位置を対応づけて検索を高速化する仕組み。

INTERACTIVE VISUALIZATION
フルスキャン
インデックス
ヒット
フェーズ
idle
探す対象
E07
調べた回数
0
シナリオ
ステップ1 / 7
STEP 1/7社員テーブルを用意する社員テーブルには6件のデータが、登録した順(格納位置1〜6)にバラバラに並んでいます。ここから社員ID「E07(伊藤さん)」の行を探したい、というのが目標です。インデックス(索引)がない状態から始めます。
社員テーブル(格納順)
位置社員ID名前
1E05佐藤
2E02鈴木
3E08田中
4E01高橋
5E07伊藤
6E03渡辺
探す手間の比較
フルスキャン(索引なし)
先頭から1件ずつ確認 → 5回 の比較で発見。件数が増えるほど遅くなる。
インデックス利用
キー順の索引で位置を特定 → 数回 で格納位置5へ直接到達。件数が増えても伸びが小さい。
解説

📌
インデックスとは

索引E07→ 位置5本体(位置5)伊藤

インデックス(索引)とは、列の値(検索キー)と、その行が置かれている格納位置を対応づけて、検索を高速化する仕組みのことです。データ本体とは別に、検索用の小さな案内表を用意するイメージです。

身近な例で考えると、分厚い本の巻末にある索引(さくいん)とまったく同じ仕組みです。調べたい言葉が本文のどこにあるか、最初のページから順に探すのは大変ですが、索引を見れば「その言葉は123ページ」とすぐ分かります。インデックスは、この「言葉→ページ番号」の対応を、データベースの「検索キー→格納位置」として持っているわけです。

上のツールで▶ボタンを押すと、索引がない場合(フルスキャン)と、索引を使う場合とで、目的の行にたどり着く手間がどれだけ違うかを見比べられます。

高速化の仕組み

フルスキャン5回も調べるインデックス数回で到達

インデックスがないと、データベースは目的の行を見つけるために先頭から1件ずつ全部の行を調べるしかありません。これをフルスキャン(全表走査)と呼びます。100万件あれば最悪100万回近く調べることになります。

インデックスが速い理由は、次の2点にあります。
キー順に整列している:索引は検索キーの順に並んでいるので、目的の値を二分探索(=半分ずつ範囲を絞る探し方)などで少ない回数で見つけられる
格納位置を直接指す:見つけたエントリには「行の格納位置」が書いてあるので、本体のその位置へ一気にジャンプできる

つまり、全部を順に見る代わりに、整列した索引で当たりをつけて目的地へ直行するのがインデックスの高速化の正体です。多くのデータベースでは、この索引を木構造(B-tree)で持つことで、データが増えても探す回数の伸びをとても小さく抑えています。

⚖️
メリットとデメリット

インデックスは検索を速くする便利な仕組みですが、万能ではなく代償もあります。良い面と注意点をセットで理解しておくことが大切です。

メリット
検索が速い:目的の行へ少ない手数で到達
並べ替えにも有効:整列済みなので順序付けが楽
件数が多いほど効果大
デメリット
記憶容量を消費:本体とは別に索引の場所が要る
更新が重くなる:行の追加・更新・削除のたびに索引も直す
作りすぎると逆効果

本の索引を作るのに手間とページがかかり、本文を書き直すたびに索引も直す必要があるのと同じです。そのため、検索でよく条件に使う列にだけインデックスを作り、更新が頻繁な列には作りすぎないのが上手な使い方です。何でもかんでも索引を付ければ速くなる、というわけではない点に注意しましょう。

🌲
なぜ木構造だと速いのか

E05E02E08E01E03E07 ✓E09E07 を探す:E05→右→E08→左 で 3手で到達

実際のデータベースでは、インデックスを木(ツリー)の形で持っています。もっともよく使われるのがB木(B-tree)という構造です(Bはバランスの略と思えばOK)。

木構造が速い理由は「比べるたびに半分ずつ候補が減る」からです。上の図を例にすると、
ルート(根):まずここのキーと比べる(例:E05)
目的の値がそれより大きければ右、小さければ左へ進む
・これを繰り返すと、1回比べるたびに探す範囲が半分になる

たとえば100万件のデータでも、木の深さは約20段程度(2の20乗=約100万)。つまり最悪でも20回比べれば見つかるのに対し、全部を順に調べると最大100万回かかります。件数が増えても比べる回数がほとんど増えないのが、木構造の最大の強みです。

🔑
どの列にインデックスを作るか

インデックスが効く列 vs 効かない列効く(作るべき)・検索条件によく使う列・値の種類が多い列例)社員ID・メールアドレス効きにくい・更新が頻繁な列・値の種類が少ない列例)性別・フラグ(0/1)

インデックスを作るほど速くなるわけではありません。どの列に作るかの判断が大切です。効果が高いのは次のような列です。
検索でよく使う列WHERE 列名 = 値 のように条件に指定される列
値の種類が多い列(=特定の値に絞ると件数がぐっと減る列):社員IDやメールアドレスなど

逆に、効果が薄い・むしろ逆効果になるのは次のような列です。
値の種類が少ない列:「性別(男・女)」「フラグ(0か1)」は索引を引いても大量の行が残り、あまり絞れない
更新が非常に頻繁な列:行を追加・変更するたびに索引の書き直しが発生し、更新が重くなる

本の巻末索引で考えると、「は・ひ・ふ・へ・ほ」のページを全部载せても絞れませんが、「特定の専門用語」なら1ページに絞れます。それと同じで、索引が役立つのは「その値で大幅に件数が絞り込める」ときだけです。

練習問題

🎯
基本情報技術者 練習問題

Q1.データベースのインデックス(索引)の説明として最も適切なものはどれか。
A.テーブルのデータ本体を複製してバックアップする仕組み
B.列の値とその行の格納位置を対応づけ、検索を高速化する仕組み
C.表どうしを結合条件でつなぐ仕組み
D.行を条件で絞り込む演算
Q2.インデックスがあると検索が速くなる主な理由はどれか。
A.すべての行を先頭から順に調べるようになるため
B.キー順に整列した索引から目的の格納位置を少ない回数で特定し、直接アクセスできるため
C.データ本体が自動的に小さく圧縮されるため
D.CPUのクロック周波数が上がるため
Q3.インデックスのデメリットとして適切なものはどれか。
A.検索が必ず遅くなる
B.記憶容量を追加で消費し、データ更新時にインデックスの更新コストもかかる
C.テーブルのデータが消えてしまう
D.デメリットは一切ない

関連コンテンツ