最終曎新:

【仕組み解説】デヌタベヌスのむンデックスはなぜ速い — B-Treeの仕組みを図解


むンデックス怜玢 vs フルテヌブルスキャン B-Tree むンデックス 50 20 | 35 65 | 80 5,10 25,30 40,45 55,60 70,75 85,90 WHERE id = 70 → 3回の比范でヒット 蚈算量: O(log n) フルテヌブルスキャン id=1 name=田侭 id=2 name=䜐藀 id=3 name=鈎朚 ... id=70 name=山田 ← ヒット ... 残り党行もチェック 先頭から1行ず぀党件走査 蚈算量: O(n) 100䞇件のテヌブルで id=70 を怜玢した堎合 B-Tree: 箄20回の比范 フルスキャン: 最倧100䞇回
B-Treeむンデックスずフルテヌブルスキャンの比范
ひよこ ひよこ
デヌタベヌスが遅いっお話をよく聞くけど、むンデックスを貌るず速くなるっお本圓
ペンギン先生 ペンギン先生
本圓だよ。たず「むンデックスがない状態」を想像しおみよう。100䞇行のテヌブルから1件探すずき、DBは先頭から1行ず぀党郚チェックしおいく。これを「フルテヌブルスキャン」ずいうんだ。本で蚀えば、目次も玢匕もなしに1ペヌゞ目から党ペヌゞめくっお探すようなものだね。
ひよこ ひよこ
それは確かに遅そう 。むンデックスがあるずどう倉わるの
ペンギン先生 ペンギン先生
むンデックスは、たさに「本の玢匕さくいん」ず同じ仕組みだよ。玢匕には「キヌワヌド → ペヌゞ番号」が䞊んでいるよね。DBのむンデックスも「カラムの倀 → 行の堎所」を敎理しお保持しおいるんだ。だから党行を芋なくおも、玢匕をたどるだけで目的のデヌタに䞀発でたどり着ける。
ひよこ ひよこ
なるほどでも玢匕っおどういう構造で敎理されおいるの
ペンギン先生 ペンギン先生
最も䞀般的なのが「B-Treeビヌツリヌ」ずいう朚構造だよ。PostgreSQLも、CREATE INDEXで皮類を指定しなければB-Treeを䜜る。根ルヌトから枝分かれしおいっお、葉リヌフに行の圚りかを瀺す情報がある。たずえば100䞇件のデヌタでも、B-Treeなら玄20回の比范で目的の行にたどり着ける。蚈算量でいうず O(log n) で、フルスキャンの O(n) ず比べるず桁違いに速いんだ。
ひよこ ひよこ
葉っぱには行の堎所が曞いおあるんだね。デヌタそのものじゃないの
ペンギン先生 ペンギン先生
そこはDBによっお違うんだ。MySQLのInnoDBだず䞻キヌの「クラスタむンデックス」の葉に行デヌタそのものが入っおいお、玢匕をたどるずそのたたデヌタのペヌゞに着く。䞀方でそれ以倖の玢匕セカンダリむンデックスの葉には䞻キヌの倀が入っおいお、そこからもう䞀床クラスタむンデックスを匕き盎すんだよ。「葉ポむンタ」ず䞞暗蚘せず、䜿っおいるDBの構造を確認するのが倧事だね。
ひよこ ひよこ
O(log n) っおこずは、デヌタが倍に増えおも比范回数は1回しか増えないっおこず
ペンギン先生 ペンギン先生
その通り100䞇件で玄20回、200䞇件でも玄21回。これがB-Treeの匷さだね。ちなみに朚の各ノヌドは耇数のキヌを持おるから、ディスクの読み取り回数も最小限に抑えられる蚭蚈になっおいるんだ。
ひよこ ひよこ
耇合むンデックスっおいうのも聞いたこずがあるけど、普通のむンデックスず䜕が違うの
ペンギン先生 ペンギン先生
耇合むンデックスは、耇数のカラムをたずめお1぀のむンデックスにしたものだよ。たずえば「姓」ず「名」で耇合むンデックスを䜜るず、「姓田䞭 AND 名倪郎」の怜玢が1぀のむンデックスだけで枈む。ただし順番が重芁で、「姓, 名」の順で䜜ったむンデックスは「姓」だけの怜玢にも䜿えるけど、「名」だけの怜玢には䜿えない。電話垳が「姓 → 名」の順で䞊んでいるのず同じ理屈だね。
ひよこ ひよこ
カバリングむンデックスっおいうのもあるっお聞いたけど、それは䜕
ペンギン先生 ペンギン先生
カバリングむンデックスは、ク゚リが必芁ずするカラムがすべおむンデックスに含たれおいる状態のこずだよ。通垞はむンデックスで行の䜍眮を芋぀けおから、テヌブル本䜓にデヌタを取りに行く。でもカバリングむンデックスなら、むンデックスだけで結果を返せる可胜性がある。PostgreSQLではこれを「むンデックスオンリヌスキャン」ず呌ぶんだ。
ひよこ ひよこ
「可胜性がある」っお、必ず速くなるわけじゃないの
ペンギン先生 ペンギン先生
そう、ここが誀解されやすいずころ。PostgreSQLのむンデックスには「その行が今芋えおいいかどうか」の可芖性情報が入っおいなくお、テヌブル偎にしかないんだ。だから可芖性マップのビットが立っおいないペヌゞは、結局テヌブルを芋に行くこずになっお普通のむンデックススキャンず倉わらなくなる。曎新が頻繁なテヌブルでカラムを詰め蟌んでも期埅どおりには効かない、ずいうこずだね。
ひよこ ひよこ
じゃあ党郚のカラムにむンデックスを貌れば最匷っおこず
ペンギン先生 ペンギン先生
それが萜ずし穎なんだ。むンデックスは「読み取りを速くする代わりに、曞き蟌みを遅くする」ずいうトレヌドオフがある。INSERT や UPDATE のたびに、テヌブル本䜓だけでなくむンデックスも曎新しなきゃいけないからね。むンデックスが10個あれば、1回のINSERTで11箇所テヌブルむンデックス10個を曎新するこずになる。ストレヌゞ容量も食うし、貌りすぎは逆効果だよ。
ひよこ ひよこ
むやみに貌っちゃダメなんだね 。効果があるか確認する方法っおあるの
ペンギン先生 ペンギン先生
EXPLAINコマンドを䜿うずいいよ。SQLの先頭に EXPLAIN を぀けるず、DBがそのク゚リをどう実行するか実行蚈画を教えおくれる。「Seq Scan」ず出たらフルスキャン、「Index Scan」ず出たらむンデックスが䜿われおいる。PostgreSQLなら EXPLAIN ANALYZE を぀けるず実際の実行時間も衚瀺されるから、むンデックスの効果を数倀で確認できるんだ。
ひよこ ひよこ
B-Tree以倖のむンデックスもあるの
ペンギン先生 ペンギン先生
あるよ。代衚的なのが「ハッシュむンデックス」だね。ハッシュ関数で倀を倉換しお、盎接デヌタの堎所を割り出す方匏だ。完党䞀臎怜玢WHERE id = 100なら O(1) で B-Tree より速い堎合もある。ただし範囲怜玢WHERE id BETWEEN 1 AND 100や ORDER BY には䜿えないずいう倧きな制玄がある。だから汎甚性の高い B-Tree がデフォルトで䜿われるこずがほずんどだね。
ひよこ ひよこ
むンデックスの蚭蚈っお奥が深いんだね 。実務ではどう刀断すればいいの
ペンギン先生 ペンギン先生
基本方針は3぀。たず WHERE 句や JOIN 条件に頻繁に䜿うカラムにむンデックスを貌るこず。次に、カヌディナリティ倀の皮類数が高いカラムを優先するこず。性別のように2皮類しかない列はむンデックスの恩恵が薄い。最埌に、定期的に EXPLAIN で実行蚈画を確認しお、䞍芁なむンデックスは削陀するこず。「必芁なものだけを、必芁な順序で」が鉄則だよ。

参考資料

確認日2026幎9月23日。挙動はDB補品ずバヌゞョンで異なるため、実際の刀断は䜿甚䞭のDBの公匏ドキュメントで確認しおください。

  • PostgreSQL: Index Types — CREATE INDEXの既定はB-Tree。ハッシュむンデックスは等䟡比范=のみ扱える
  • PostgreSQL: Index-Only Scans and Covering Indexes — 可芖性情報はむンデックスになく、可芖性マップ次第でテヌブル参照が発生する
  • PostgreSQL: Using EXPLAIN — 実行蚈画の読み方ず EXPLAIN ANALYZE
  • MySQL: Clustered and Secondary Indexes — クラスタむンデックスの葉に行デヌタが入り、セカンダリむンデックスは䞻キヌ倀を保持する