巨大なデータを「本棚」から探すなら?PostgreSQLの「BRINインデックス」という裏技
こんにちは!データベースの世界に足を踏み入れると、「データが増えすぎて検索が遅い…」なんて壁にぶつかること、ありますよね。
そんな時、真っ先に思い浮かぶのは「インデックス(索引)」という救世主ですが、実はデータが数億行、数十億行と膨大になると、普通のインデックスを作るだけでディスク容量がパンクして、逆にシステムが重くなってしまう……なんて皮肉な事態も起こり得るんです。
そこで今回は、そんな「超巨大なデータ」を相手にする時にこそ輝く、BRIN(Block Range Index)というちょっと賢いインデックスについて、一緒に紐解いていきましょう。
—
本の「索引」と「目次」の違い
普通のインデックス(B-treeインデックスといいます)は、言ってみれば「辞書の巻末にある詳細な索引」です。すべての単語がどこにあるか網羅されているので、ピンポイントで探すには最強です。
でも、もしその辞書が「東京ドームくらいの広さ」にあったらどうでしょう? 索引を作るだけで、もう一冊分くらいの巨大な本が必要になってしまいますよね。
ここで登場するのがBRINです。BRINは「索引」というより、「本棚の端っこに貼られた付箋」に近いイメージです。
- 「この本棚のエリアには、AからCまでの本が入っていますよ」
- 「あっちのエリアには、DからFの本がありますよ」
これだけです。詳細な場所は書かれていませんが、「少なくともここには該当する本はないな」ということが瞬時に分かりますよね。この「ざっくりとした情報」だけで管理するので、インデックスのサイズが驚くほど小さくて済むんです。
—
物理的な「順番」が命!
BRINがうまく機能するための最大のポイントは、「データが物理的に並んでいること」です。
例えば、時系列データのように「古い順」にデータが書き込まれているテーブルなら、BRINは最高のパフォーマンスを発揮します。
「2023年1月のデータ」を探すとき、BRINなら「あ、このエリアは2020年〜2021年のデータしか入ってないからスルーしよう」と、ごっそり読み飛ばすことができるからです。
逆に、データがバラバラに混ざり合っていると、BRINは「どこを見ても該当しそうに見える……」となってしまい、せっかくの付箋も役に立ちません。BRINは「整頓されている場所」が大好きなインデックスなんです。
—
「pages_per_range」で賢くチューニング
BRINを使うとき、一つだけ設定しておきたいのが `pages_per_range` という項目です。これは、「付箋一枚につき、どれくらいの範囲のデータを担当させるか」を決める設定です。
- 数字を小さくすると…
- 付箋が増えるので、より細かく場所を特定できます。でも、その分管理が少し大変になります。
- 数字を大きくすると…
- ざっくりとした管理になります。インデックスはさらに小さくなりますが、探す範囲が広くなりすぎて、一度に読み込むデータ量が増えてしまう可能性があります。
「どのくらいの粒度で付箋を貼るのがベストか?」は、データの量や増え方によって変わります。最初はデフォルトのままでも十分速いことが多いですが、もし「もう少し速くしたいな」と感じたら、この数字を少しずつ調整してみるのも、エンジニアとしての醍醐味ですよ。
—
まとめ:適材適所で使いこなそう
BRINは魔法の杖ではありません。普通のインデックスのように「ここだ!」と一発で正解を当てることはできませんが、「ここには絶対にない」と判断する能力においては右に出るものはいません。
- 普通のインデックス(B-tree):ピンポイントで探したい時、データがそこまで巨大ではない時。
- BRIN:数億行レベルの超巨大データで、かつ日時順などで整理されている時。
このように、相手のデータの形に合わせて「道具」を選べるようになると、データベースの運用がぐっと楽しくなりますよ。
皆さんのシステムでも、もし「インデックスが大きすぎて困っている」という巨大なテーブルがあれば、ぜひ一度BRINを検討してみてくださいね。それでは、また次回の記事でお会いしましょう!
コメント