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

巨大なデータを「本棚」から探すなら?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を検討してみてくださいね。それでは、また次回の記事でお会いしましょう!

コメント

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