こんにちは!データベースをこよなく愛するエンジニアです。
皆さんは、PostgreSQLの「インデックス」と聞いて、何を思い浮かべますか?「とりあえずB-treeを作っておけば安心!」という方も多いかもしれませんね。それは決して間違いではありません。むしろ大正解です。
でも、たまには「ちょっと変わった子」にもスポットライトを当ててみたくありませんか?今日は、そんな少し尖った特技を持つ「Hash(ハッシュ)インデックス」という存在について、お話ししようと思います。
—
インデックスは「辞書」か「背番号」か
まず、皆さんが普段よく使う「B-treeインデックス」をイメージしてみてください。これは「辞書」のようなものです。言葉が順番に並んでいるから、「あ」から「い」へと順番に探したり、範囲を絞り込んだりするのが得意ですよね。
一方で、今回の主役である「Hashインデックス」は、辞書というよりは「ロッカーの番号札」に近いかもしれません。
例えば、大きな駅のコインロッカー。荷物を預けるときに、適当な番号のロッカーに放り込みますよね。後で取り出すときも、「何番のロッカーに入れたか」さえ分かれば、一瞬で取り出せます。でも、「番号順に並べろ」と言われても、ロッカー自体はバラバラに配置されているので、それは無理な相談です。
これが、Hashインデックスの最大の特徴なんです。
Hashインデックスが得意なこと・苦手なこと
Hashインデックスは、まさに「特定の値がどこにあるか」をピンポイントで引き当てる天才です。
- 得意: 「`user_id = 12345` はどこ?」というような、ピッタリ一致するデータの検索。
- 苦手: 「`user_id > 100`」とか「`name LIKE ‘A%’`」のような、範囲指定や曖昧検索。
B-treeが「順番に並んでいるから範囲検索もできるよ!」という優等生なら、Hashは「とにかく一発で当てます!」という一点突破型の職人さんなんです。
なぜHashインデックスを使うの?
「じゃあ、B-treeでいいじゃん!」と思いましたよね?鋭いです。でも、Hashインデックスには独自の魅力があるんです。
1. メモリ効率の良さ
B-treeは、データの順番を維持するために、木の枝分かれのような複雑な構造をメモリ上に保ち続けなければなりません。データ量が増えると、この「木」の管理が少し重たくなることもあります。
一方、Hashインデックスは非常にシンプルな計算式で場所を特定します。そのため、インデックス自体がB-treeよりも小さく収まることが多く、メモリの節約になるケースがあるんです。
2. 検索速度の安定感
データ量が膨大になっても、Hashインデックスの検索スピードは驚くほど変わりません。「計算して、その場所を見る」という手順が変わらないからです。B-treeのように「木を深く潜っていく」必要がないので、特定条件下では非常にキビキビと動いてくれます。
ただし、これだけは注意して!
ここまで読んで「よし、全部Hashに変えよう!」と思った方、ちょっと待ってくださいね。
- 等価比較しかできない: 「=」以外には使えません。範囲検索に使おうとすると、データベースは「あ、これHashじゃ無理だわ」と諦めて、全データを舐めるような非効率な動き(フルスキャン)をしてしまいます。
- 「並び順」は無視: 「IDの大きい順に並べて表示して!」というような処理も、Hashインデックスではお手上げです。
—
最後に:使い分けのヒント
結局、どちらがいいのか?
- 普段はB-treeでOK! 迷ったらまずはB-treeです。多くのケースで最適解になります。
- Hashは「特定のID検索」が異常に多い時に! システムの要となる巨大なテーブルで、特定のキー検索だけがボトルネックになっている場合、Hashインデックスが特効薬になることがあります。
データベースのチューニングって、魔法のような近道があるわけじゃなくて、こうした「適材適所」を見極める積み重ねなんですよね。
皆さんのデータベースにも、もしかしたら「Hashインデックスが活躍できる場所」が隠れているかもしれません。ぜひ一度、実行計画(EXPLAIN)を眺めながら、「ここはピンポイント検索が多いから、Hashの方が軽くなるかも?」なんて想像を膨らませてみてください。
それでは、また次回の記事でお会いしましょう!Happy Query Life!
コメント