こんにちは!データベースエンジニアとして日々データと向き合っていると、たまに「このテーブル、一体いつまで大きくなり続けるの……?」と途方に暮れたくなるような巨大なデータに出くわすことがあります。
そんな時、普通のインデックス(B-treeインデックスといいます)を作ろうとすると、インデックスだけでサーバーのメモリがパンパンになってしまったり、ディスクを圧迫して悲鳴を上げたりするんですよね。
今日は、そんな「超巨大テーブル」の救世主、PostgreSQLの「BRINインデックス」というちょっと面白い仕組みについてお話しします。
—
本棚の「背表紙」を想像してみてください
皆さんが図書館にいると想像してください。100万冊ある本の中から「ある特定の本」を探したいとき、どうしますか?
通常、私たちは「索引(インデックス)」を使いますよね。本のタイトル順に並んだリストを見れば、どの棚のどこにあるかがすぐに分かります。でも、もしそのインデックス自体が分厚い辞書のように重くて、持ち運ぶのも大変だったらどうでしょう?
そこで登場するのが「BRIN(Block Range Index)」という考え方です。
BRINは、本を一冊ずつ管理するのではなく、「この棚には『あ』から『え』までの本が入っている」という、ざっくりしたメモを棚に貼っておくようなイメージなんです。
BRINがやってくれること:緻密さより「大枠」を掴む
通常のインデックスは、すべてのデータの居場所を完璧に把握しようとします。だからこそ正確で速いのですが、その分、インデックス自体が肥大化してしまいます。
一方でBRINは、「データの物理的な並び順」という特性をうまく利用します。
例えば、ログデータのように「時間が経つごとに後ろに追加されていくデータ」を想像してください。
- ブロック1:2023年1月1日〜1月10日のデータが入っている
- ブロック2:2023年1月11日〜1月20日のデータが入っている
BRINは、「このブロックにはこの期間のデータがあるよ!」という範囲(レンジ)だけを記録します。たったこれだけのことですが、これが驚くほど効率的なんです。
BRINを使うメリット
- サイズがめちゃくちゃ小さい: 巨大なテーブルでも、インデックスのサイズはほんの数メガバイト程度で済むこともあります。
- メンテナンスが楽: データが増えてもインデックスが重くなりにくいので、運用がすごく楽なんです。
ただし、ちょっとした「弱点」もあります
BRINは「ざっくりしたメモ」なので、B-treeのように「このデータはここだ!」とピンポイントで当てるのは少し苦手です。
「だいたいこの辺りにありそうだから、この棚の中身を全部見てみよう」という探し方をするので、読み込みは少しだけ大雑把になります。でも、巨大なテーブル全体をスキャンするよりは、はるかに速いんですよ。
—
どんなときに使うのが正解?
BRINは魔法の杖ではありません。使いどころを間違えると逆効果になることもあります。こんな条件に当てはまるなら、ぜひ検討してみてください。
- テーブルが数億行、あるいはテラバイト級に巨大であること
- データが「時間」や「ID」のように、ある程度の規則性を持って物理的に並んでいること
- 「全部探すのは無理だけど、ある程度の範囲を絞り込めれば十分速い」という用途
具体的には、Webサーバーのアクセスログや、センサーから送られてくる大量の計測データなんかにはピッタリです。
—
まとめ
BRINは、「正確さ」を少し手放す代わりに、「圧倒的な軽さ」を手に入れるという、潔いインデックスです。
「データベースのパフォーマンスが落ちてきたな……」と悩んでいるなら、まずは一度、そのテーブルのデータがどんな順序で並んでいるか確認してみてください。もし時系列で並んでいるなら、BRINがあなたの救世主になってくれるかもしれません。
インデックス設計は、まさに「バランス感覚」の勝負です。完璧を求めすぎて重いインデックスを作るよりも、時にはBRINのような賢い「大まかな整理術」を取り入れてみる。そんな柔軟な視点が、エンジニアとしての武器になるはずですよ。
それでは、また次回の記事でお会いしましょう!Happy Querying!
コメント