※ この記事にはアフィリエイトリンクが含まれます
この記事では、
- そもそも VACUUM が何をしているのか
- 放置したときにどんな問題が起きるのか
- 手動で VACUUM を入れるべきケースとは?
- 定期的に実行すべきかどうかの判断基準
を、実務目線でわかりやすく解説していきます。
「VACUUMをしないと本番がどうなる?」
「定期的にやったほうがいいの?」
と疑問を持っている方の参考になれば幸いです。
VACUUM(バキューム)とは?
PostgreSQLのパフォーマンスを語るうえで欠かせないのがVACUUM(バキューム)です。VACUUMがどいうものなのか見ていきましょう。
PostgreSQL は MVCC(Multi-Version Concurrency Control) という仕組みでデータの同時更新を管理しています。
この方式では、UPDATE や DELETE を行うたびに “古い行” が残り続けるという特徴があります。
UPDATE users SET name='A' WHERE id=1;このとき PostgreSQL は、
- 古い行:削除予定(無効)
- 新しい行:有効データ
という 2つの行をテーブル内に残す仕組みになっています。
この「もう参照されることのない古い行」が、いわゆる デッドタプル(不要な行)。
VACUUMの役割
VACUUM は、このデッドタプルを処理して、
- もう使わない行を“再利用可能”な状態に戻し
- テーブルやインデックスが肥大化しないようにする
という 掃除係のような役割を担っています。
VACUUMの種類
PostgreSQLには2種類あります。
VACUUM(通常のバキューム)
- デッドタプルの整理
- ストレージの再利用可能化
- インデックスの掃除(必要に応じて)
- 軽めの処理でテーブルロックはかからない
→ 普段のメンテナンス向け
VACUUM FULL
- テーブル全体を丸ごと作り直す
- 実際にディスク容量を削減する
- 排他ロックがかかる(アクセス不可)
→ ディスク逼迫や大規模肥大化時の最終手段
なぜ自動で消えないの?
「不要な行なら自動で消えてくれればいいのに」と思うかもしれません。
しかし、PostgreSQLは高い同時実行性を保つため、消すタイミングを慎重にコントロールしています。
複数トランザクションが同じテーブルを参照していると、
「どのトランザクションから見て”不要”なのか」
という判断が必要になるからです。
そのため、
専用の掃除処理(VACUUM)で安全にデッドタプルを処理している
というわけですね。
AUTOVACUUM(オートバキューム)の仕組み
PostgreSQLには、手動でVACUUMを実行しなくても、バックグラウンドで自動的に掃除してくれるautovacuum(オートバキューム)という仕組みがあります。
PostgreSQLではデフォルトでAUTOVACUUMが備わっています。
AUTOVACUUMがやってくれること
オートバキュームは、以下の2つの掃除を自動実行します。
- VACUUM(通常のバキューム)
- ANALYZE(統計情報の更新)
これにより、
- デッドタプルが溜まるのを防ぐ
- オプティマイザが正しい実行計画を選べる
など、アプリ全体のパフォーマンス維持に大きく貢献しています。
AUTOVACUUMの起動条件
オートバキュームは”勝手に定期実行される”わけではありません。
基本は以下の条件に当てはまったときに起動します。
デッドタプルの数が閾値を超えたとき
以下の公式で計算される値を起動します。
autovacuum_vacuum_threshold
+ autovacuum_vacuum_scale_factor * テーブルの行数デフォルト値はわりと緩い(スケールファクタ 0.2)ため、
大きいテーブルほど「デッドタプルがめちゃくちゃ溜まってから」起動する傾向があります。
例:1,000,000 行のテーブル
→ デフォルトだと 20万行のデッドタプル が溜まらないと動かない
これは実務では“かなり遅い”部類です。
AUTOVACUUMのメリット
- 完全自動で動く
- PostgreSQL の標準機能
- 負荷が上がらないように優先度が低く設定されている
- 手動管理が不要になる
普通のWebサービスや業務システムなら、
AUTOVACUUMだけで十分に安定するケースが多いです。
AUTOVACUUMの弱点
オートバキュームは便利ですが、万能ではありません。
実務では以下の弱点がしばしば問題になります。
大きいテーブルでは間に合わない
0.2 ×行数が閾値なので、大規模テーブルほど発動が遅くなります。
数百万~数千万行クラスでは、
起動する頃にはテーブルがすでに肥大化している
ということも珍しくありません。
UPDATE、DELETEが頻繁なテーブルでは追いつかない
1日何十万件も更新があるテーブルだと、
掃除が追いつかず、テーブル・インデックスがどんどん肥大化します。
結果として、
- 検索が遅い
- インデックスが無駄に巨大
- ディスク使用量が急増
といった症状が出ます。
VACUUMしないと何が起きる?
VACUUM を適切に実行しないと、PostgreSQL は少しずつ“性能劣化”していきます。
普段は静かに進むため気づきにくいですが、気づいたときには 「なんか最近クエリ遅くない?」 という状態になってしまいます。
ここでは、VACUUM をサボる(=デッドタプルを放置する)ことで発生する典型的な問題を整理します。
テーブル肥大化(ディスク容量の無駄消費)
デッドタプルが残り続けると、その分だけテーブルサイズがどんどん大きくなります。
例100万行あるテーブルで毎日10万件更新があるとデッドタプルが何十万、
何百万と蓄積することも珍しくありません。
結果として、
- テーブルサイズが5倍
- インデックスサイズが10倍
になることすらあります。
ディスク容量を圧迫するだけでなく、クエリ性能にも直結するのが厄介なところです。
インデックス肥大化→検索が遅くなる
実務で一番影響が出やすいのがここです。
デッドタプルはテーブルだけでなく インデックス側にも蓄積 されます。
そうなると、
- インデックスのページが増える
- ツリーが深くなる
- 参照コストが上がる
という悪循環になり、単純な SELECT でも処理が遅くなります。
「検索が遅い」と感じたとき、実は原因が
クエリではなくインデックスの肥大化
というケースは非常に多いです。
UPDATE、DELETEが遅くなる
デッドタプルが多いテーブルでは、
更新対象の探索に時間がかかるため、
UPDATE や DELETE 自体も遅くなります。
具体的には、
- 更新対象を探す
- 過去バージョンを無効化する
- 新しいタプルを書き込む
という一連の処理が
「膨大な不要データの中からの探索」
になってしまうため、かなりのオーバーヘッドになります。
まとめ
PostgreSQL のパフォーマンスを安定させるうえで、VACUUM は欠かせないメンテナンス作業です。
「オートバキュームがあるから放置でOK」と思われがちですが、実務ではそうとも限りません。
PostgreSQL は「しっかり掃除してあげれば長く安定して動く」データベースです。
もし最近クエリが遅い、テーブルが大きい、オートバキュームが動いていない気がする…
という場合は、一度 VACUUM の状況を点検してみることをおすすめします。
つけたい方には、RareTECHをチェックしてみてください。実案件ベースのカリキュラムで、あなたのスキルを次のステージへ引き上げてくれるはずです。

なんくる「本当にエンジニアとしてやっていけるか不安…」という方も、実践的な開発に関わることで、転職後の働き方を事前に体感できますよ。
実務で使えるDBスキルとともに、プログラミングスキルをちゃんと身につけたいなら、
RareTECHの無料カウンセリングで、学ぶ目的やゴールをプロと一緒に明確にしてみましょう。独学では得られない「実践的な成長の道筋」が見えてきます。


もしこの内容を通して、PostgreSQLについてさらに理解を深めたいと感じられたなら、信頼できる講座や書籍を紹介した別記事をご覧いただくのも良いかと思います。ご自身の学びに、きっとお役立ていただけるはずです。










コメント