こんにちは!データベースの世界にどっぷり浸かって十数年、今日も元気にクエリをチューニングしているエンジニアです。
皆さんは、PostgreSQLを使っていて「あれ?最近なんだか検索が遅くなった気がする…」なんて経験はありませんか?実はそれ、データベースの「お片付け」が追いついていないせいかもしれません。
今日は、そんなデータベースのちょっとした悩み、「インデックスの肥大化(Bloat)」について、専門用語を抜きにしてお話ししてみようと思います。
—
インデックスの肥大化って、つまりどういうこと?
皆さんは、本棚を想像してみてください。本を探すとき、「索引(インデックス)」を見ればどこにあるかすぐ分かりますよね。データベースのインデックスも、まさにこれと同じです。
では、「頻繁に書き換えられるメモ帳」を本棚に置いていると想像してください。
1. メモ帳の内容を書き換えるたびに、古い内容を消して、新しい内容を書き込む。
2. そのたびに索引も「修正」が必要になります。
3. でも、PostgreSQLは律儀なので、古いメモの跡地をすぐには完全に綺麗にせず、「ここは空いたけど、また使うかもしれないから取っておこう」と、「使えない隙間」をたくさん残してしまうんです。
この「使えない隙間」が積み重なるとどうなるでしょう?索引(インデックス)の本が、中身はスカスカなのに、ページ数だけが無駄に分厚くなってしまいますよね。これが「インデックスの肥大化(Bloat)」です。
索引が分厚くなれば、お目当てのデータを探すのに、それだけたくさんのページをめくらなきゃいけません。結果として、検索が遅くなってしまうんです。
—
肥大化しているか、どうやって見抜くの?
「自分のデータベースが太っちゃってるかどうか知りたい!」というとき、PostgreSQLには便利なツールがたくさんあります。
一番手軽なのは、コミュニティで公開されている`pgstattuple`という拡張機能を使う方法です。これを使うと、「今のインデックス、実は何%が無駄な隙間なんですよ」と、残酷なほど正確に教えてくれます。
「難しいコマンドはちょっと…」という方は、まずは「最近、更新頻度がめちゃくちゃ高いテーブルがあるな」という直感を信じてみてください。更新が多い場所は、間違いなく肥大化の温床です。
—
どうやって解消すればいいの?
太ってしまったインデックスをスリムにする方法は、大きく分けて2つあります。
1. VACUUM(バキューム)という「お掃除屋さん」
PostgreSQLには、`VACUUM`という標準機能があります。これは、データベースの中を回って「もう使われていない隙間」を回収し、「次からはここを使っていいよ」と再利用可能にしてくれるお掃除屋さんです。
基本的には、PostgreSQLが自動でやってくれる設定(Autovacuum)が入っているはずですが、あまりに更新が激しい場合は、お掃除が追いつかないことも。そんなときは、手動で`VACUUM`をかけてあげるのが一番の近道です。
2. REINDEX(再構築)という「禁断の技」
どうしても肥大化がひどくて、隙間がバラバラに散らばって整理がつかない…!という場合は、`REINDEX`という荒療治を使います。
これは、インデックスを「一度捨てて、最初から綺麗に作り直す」という方法です。本棚の索引を一旦全部剥がして、最新の状態に合わせて完璧に書き直すイメージですね。非常にスッキリしますが、作り直している間は少しデータベースに負荷がかかるので、アクセスが少ない夜中などにこっそり行うのがコツですよ。
—
最後に:完璧を目指しすぎないで
初心者の頃は、「インデックスを常に100%完璧な状態に保たなきゃ!」と意気込んでしまいがちですが、実はそこまで神経質になる必要はありません。
データベースは、ある程度「遊び」があるほうが安定して動くものです。まずは、「最近遅いな?」と感じたときに、`VACUUM`のことを思い出してあげる。それだけで、あなたのデータベースはずっと快適に動いてくれるはずです。
データベースは、まるで生き物のようなものです。時々様子を見て、優しくお手入れしてあげてくださいね。それでは、また次回の記事でお会いしましょう!
コメント