「とりあえずB-tree」卒業!PostgreSQLのハッシュインデックスを料理に例えて理解しよう
データベースを触り始めると、必ずと言っていいほど耳にするのが「インデックス」という言葉。PostgreSQLを使っていると、デフォルトで作られる「B-tree」というインデックスが万能選手すぎて、ついそればかり使いがちですよね。
でも、たまには「ハッシュインデックス」という少し変わった存在に目を向けてみませんか?今日は、このハッシュインデックスがどんなやつなのか、難しい専門用語を抜きにして、日常の風景に例えてお話ししますね。
—
「辞書」と「ロッカー」の違い
まず、普段よく使う「B-treeインデックス」は、大きな分厚い辞書だと思ってください。
辞書は「あ」から「ん」まで順番に並んでいますよね。だから、「『りんご』に近い言葉を探したい」といった範囲検索や、「『あ』で始まる言葉」といった検索が得意なんです。これぞB-treeの強みです。
一方で、今回の主役である「ハッシュインデックス」は、駅のコインロッカーのようなものです。
コインロッカーに荷物を預けるとき、あなたは「あいうえお順」なんて気にしませんよね?「3番のロッカー」と決めたら、そこにポンと入れるだけ。取り出すときも、3番の鍵さえあれば、中身が何であれ一瞬で取り出せます。
ハッシュインデックスが得意なこと
ハッシュインデックスは、まさにこの「ピンポイントでの取り出し」に特化した仕組みなんです。
- 「IDが12345のユーザーデータを探したい!」
- 「メールアドレスが『example@test.com』の人は誰?」
こういった「これとこれが同じ(等価比較)」という検索において、ハッシュインデックスは圧倒的なスピードを誇ります。B-treeのように「順序」を整理する手間を省いて、独自の計算式(ハッシュ関数)で「どこに何があるか」を直接導き出すので、無駄がないんです。
ただし、万能ではありません!
「それなら全部ハッシュインデックスでいいじゃん!」と思うかもしれませんが、ここで注意が必要です。ハッシュインデックスには、大きな弱点があるんです。
それは、「順序」という概念がないこと。
さっきのコインロッカーを思い出してください。3番のロッカーの隣には何が入っているか、外からは分かりませんよね?
これと同じで、ハッシュインデックスは以下のような検索ができません。
- 範囲検索ができない:「IDが100から200のユーザーを表示して」と言われても、ハッシュインデックスは「3番と58番と99番……」とバラバラに計算してしまった後なので、範囲という概念を理解できないんです。
- 並び替え(ソート)ができない:順序がないので、「登録順に並べて」といった命令も苦手です。
どんな時に使うべき?
じゃあ、結局いつ使うの?という話ですが、私の経験上、こんなケースで輝きます。
- 非常に巨大なテーブルで、特定のキー(会員番号やIDなど)での検索が頻発する場合
- 範囲検索の必要が全くなく、とにかく「特定のID」を爆速で引き出したい場合
実は昔のPostgreSQLではハッシュインデックスはあまり信頼されていなかったのですが、最近のバージョンではかなり安定して使えるようになっています。「今のインデックス、なんだか遅いな…」と感じたとき、もしそれが「特定の値の検索」だけであれば、ハッシュインデックスに変えるだけで劇的に改善する可能性があるんですよ。
—
まとめ:適材適所でデータベースを愛でよう
データベースの設計って、料理と同じで「素材の良さをどう引き出すか」だと思うんです。
- 辞書のように順番が大事なときはB-tree。
- ピンポイントで鍵を開ける快感を求めるならハッシュインデックス。
「とりあえず全部B-treeでいいや」とするのではなく、「このデータはコインロッカーに入れておいたほうが幸せかな?」なんて考えながらインデックスを設計してみると、PostgreSQLとの距離がぐっと縮まるはずです。
ぜひ、皆さんの環境でも試してみてくださいね。また次回の記事でお会いしましょう!
コメント