【入門編】 B-treeインデックスの最適化 – PostgreSQL

こんにちは!データベースの世界へようこそ。

普段、何気なくSQLを書いていると、「なぜか最近、検索が遅いな……」なんて悩むこと、ありますよね。そんな時、僕たちデータベースエンジニアが真っ先にチェックするのが「インデックス」です。

今日は、PostgreSQLの標準装備である「B-tree(ビーツリー)インデックス」について、難しい専門用語はなるべく抜きにして、お話ししてみようと思います。

—

インデックスは「本の巻末索引」と同じ

データベースにインデックスを貼るというのは、「分厚い本の巻末に索引を作る」ことと全く同じです。

もし索引がない本から特定のキーワードを探そうと思ったら、最初から最後まで全ページをめくるしかありませんよね。これって、データベースでいうところの「全件スキャン(フルスキャン)」です。データが数件ならいいですが、数百万件あったら日が暮れてしまいます。

そこで登場するのが「B-treeインデックス」です。これは、僕たちが辞書を引くときのように、「大まかな範囲で絞り込んで、目的のページにたどり着く」ための賢い仕組みなんです。

B-treeインデックスが「賢い」理由

B-treeインデックスのすごいところは、「どれだけデータが増えても、たどり着くまでの手間がほとんど変わらない」という点です。

これを「木の深さ」と呼びます。
例えば、100万件のデータがあっても、B-treeなら数回の枝分かれをたどるだけで、お目当てのデータに到達できます。イメージとしては、こんな感じです。

  • 1階層目: 「あ〜さ行」か「た〜わ行」か?
  • 2階層目: 「あ」か「い」か「う」か?
  • 3階層目: その中のどのページか?

このように、階層を降りていくだけで、膨大なデータの中から一瞬で目的の場所にたどり着ける。これが、B-treeが「等価検索(=で探す)」や「範囲検索(>や<で探す)」に抜群に強い理由なんです。

意外と知らない「列の並び順」の罠

さて、ここからが今日一番伝えたい「プロのコツ」です。
複数の項目を組み合わせてインデックスを貼る(複合インデックス)とき、「順番」がめちゃくちゃ重要だって知っていましたか?

例えば、「苗字」と「名前」でインデックスを作るとします。
このとき、以下のどちらがいいと思いますか?

1. (苗字, 名前)の順で並べる
2. (名前, 苗字)の順で並べる

答えは、「左側に、より絞り込みが効くものを置く」のが正解です。

日常に例えるなら、住所を探すときに「番地」から探すよりも、「都道府県」→「市町村」→「町名」という順で絞り込むほうが圧倒的に早いのと同じです。

もし「苗字」で検索することが多いのに、インデックスを(名前, 苗字)で作ってしまうと、データベースは「名前」という大きな括りから探し始めないといけません。これだと、せっかく作った索引もあまり役に立たず、宝の持ち腐れになってしまうんです。

まとめ:インデックスは「育てていくもの」

インデックスは、ただ作ればいいというものではありません。
むやみにたくさん作ると、今度はデータの更新(追加や削除)をするたびに索引を書き直さないといけないので、逆にシステムが重くなってしまいます。

「どんな検索が一番多いかな?」
「この検索には、どの列を左側に持ってきたら一番効率がいいかな?」

そんな風に、ユーザーがどう使うかを想像しながらインデックスを設計するのは、まるで庭木の手入れをするようで、実はとってもクリエイティブで楽しい作業なんですよ。

まずは皆さんのデータベースで、一番よく使う検索クエリを見つけてみてください。そして、そのクエリが「どの列を使って絞り込んでいるか」を意識することから始めてみましょう。

きっと、データベースの反応が劇的に変わるはずです!それでは、また次の記事でお会いしましょう。

コメント

タイトルとURLをコピーしました