【入門編】 インデックスの肥大化(Bloat)と対策 – PostgreSQL

こんにちは!データベースの世界にどっぷり浸かって十数年、今日も元気にクエリをチューニングしているエンジニアです。

皆さんは、PostgreSQLを使っていて「あれ?最近なんだか検索が遅くなった気がする…」なんて経験はありませんか?実はそれ、データベースの「お片付け」が追いついていないせいかもしれません。

今日は、そんなデータベースのちょっとした悩み、「インデックスの肥大化(Bloat)」について、専門用語を抜きにしてお話ししてみようと思います。

—

インデックスの肥大化って、つまりどういうこと?

皆さんは、本棚を想像してみてください。本を探すとき、「索引(インデックス)」を見ればどこにあるかすぐ分かりますよね。データベースのインデックスも、まさにこれと同じです。

では、「頻繁に書き換えられるメモ帳」を本棚に置いていると想像してください。

1. メモ帳の内容を書き換えるたびに、古い内容を消して、新しい内容を書き込む。
2. そのたびに索引も「修正」が必要になります。
3. でも、PostgreSQLは律儀なので、古いメモの跡地をすぐには完全に綺麗にせず、「ここは空いたけど、また使うかもしれないから取っておこう」と、「使えない隙間」をたくさん残してしまうんです。

この「使えない隙間」が積み重なるとどうなるでしょう?索引(インデックス)の本が、中身はスカスカなのに、ページ数だけが無駄に分厚くなってしまいますよね。これが「インデックスの肥大化(Bloat)」です。

索引が分厚くなれば、お目当てのデータを探すのに、それだけたくさんのページをめくらなきゃいけません。結果として、検索が遅くなってしまうんです。

—

肥大化しているか、どうやって見抜くの?

「自分のデータベースが太っちゃってるかどうか知りたい!」というとき、PostgreSQLには便利なツールがたくさんあります。

一番手軽なのは、コミュニティで公開されている`pgstattuple`という拡張機能を使う方法です。これを使うと、「今のインデックス、実は何%が無駄な隙間なんですよ」と、残酷なほど正確に教えてくれます。

「難しいコマンドはちょっと…」という方は、まずは「最近、更新頻度がめちゃくちゃ高いテーブルがあるな」という直感を信じてみてください。更新が多い場所は、間違いなく肥大化の温床です。

—

どうやって解消すればいいの?

太ってしまったインデックスをスリムにする方法は、大きく分けて2つあります。

1. VACUUM(バキューム)という「お掃除屋さん」

PostgreSQLには、`VACUUM`という標準機能があります。これは、データベースの中を回って「もう使われていない隙間」を回収し、「次からはここを使っていいよ」と再利用可能にしてくれるお掃除屋さんです。

基本的には、PostgreSQLが自動でやってくれる設定(Autovacuum)が入っているはずですが、あまりに更新が激しい場合は、お掃除が追いつかないことも。そんなときは、手動で`VACUUM`をかけてあげるのが一番の近道です。

2. REINDEX(再構築)という「禁断の技」

どうしても肥大化がひどくて、隙間がバラバラに散らばって整理がつかない…!という場合は、`REINDEX`という荒療治を使います。

これは、インデックスを「一度捨てて、最初から綺麗に作り直す」という方法です。本棚の索引を一旦全部剥がして、最新の状態に合わせて完璧に書き直すイメージですね。非常にスッキリしますが、作り直している間は少しデータベースに負荷がかかるので、アクセスが少ない夜中などにこっそり行うのがコツですよ。

—

最後に:完璧を目指しすぎないで

初心者の頃は、「インデックスを常に100%完璧な状態に保たなきゃ!」と意気込んでしまいがちですが、実はそこまで神経質になる必要はありません。

データベースは、ある程度「遊び」があるほうが安定して動くものです。まずは、「最近遅いな?」と感じたときに、`VACUUM`のことを思い出してあげる。それだけで、あなたのデータベースはずっと快適に動いてくれるはずです。

データベースは、まるで生き物のようなものです。時々様子を見て、優しくお手入れしてあげてくださいね。それでは、また次回の記事でお会いしましょう!

コメント

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