Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

PostgreSQLのVACUUMやANALYZEの話

以前、Amazon Aurora PostgreSQL 11から12のバージョンアップ後に急にクエリが遅くなってしまうということがあり、VACCUUM FULL ANALYZE というコマンドを実行することで改善したのですが、このコマンドがやっていることについてよく理解できていなかったので、今回簡単にまとめてみました。

VACUUMとは

公式ドキュメントによると、VACUUMコマンドとは、データベースの不要領域の回収を行い、さらにオプションでデータベースの解析を行うことができるコマンドです。

不要領域の回収

PostgreSQLではDELETE文を実行した際、実際にはデータの消去は行われません。

削除フラグを立てて、レコードが削除された扱いにしているだけの状態になります。
そのため、何度かDELETEを繰り返していると不要データが増えていき、DBのサイズが肥大化してしまいます。
そこで VACUUM コマンドを実行することで、ゴミデータを掃除して領域を再利用可能な状態にすることができます。

また、VACUUM FULL というように FULLオプションをつけると、通常のVACUUMと比較してクリーンアップの対象が全DBになるなどして、より徹底的にゴミデータを掃除してくれます。
FULLオプションのデメリットとしては実行速度がかなり低速になり、さらにテーブルに対する排他的ロックが必要になってしまいます。

通常は autovacuum というデーモンが立ち上がっていて定期的にVACUUM処理を行ってくれるため、特にユーザーが意識して実行する必要はありません。

データベースの解析

VACUUM ANALYZE というようにANALYZEオプションをつけると、
不要領域の回収に加えて、データベースの解析を行ってくれます。

データベースの解析とは具体的にどんなことを行っているかですが、
公式ドキュメントを読むと以下のように記載されています。

ANALYZEはデータベース内のテーブルの内容に関する統計情報を収集し、その結果をpg_statisticシステムカタログに保存します。 問い合わせプランナが最も効率の良い問い合わせの実行計画を決定する際、この統計情報が使用されます。
PostgreSQL 12ドキュメント ANALYZEより

要は、プランナが最適な実行計画を決定できるようにするための統計情報を生成してくれるコマンドです。

別途 ANALYZE というコマンドが単体で用意されており、不要領域の回収は行わずにデータベースの解析だけ行いたいという場合は ANALYZE コマンドを使用します。

autovacuum と同様、こちらも autoanalyzeというデーモンが走っていて、通常は自動で解析を実行してくれます。

メジャーバージョンのアップグレード後はANALYZEが実行されない

冒頭に「Amazon Aurora PostgreSQL 11から12のバージョンアップ後に急にクエリが遅くなってしまった」と書きましたが、AWSの公式ドキュメントを読むと、PostgreSQLのメジャーバージョンをアップグレードした後は ANALYZE が自動で実行されないため、手動実行しないとパフォーマンスの問題が発生する場合があるようです。

パフォーマンスの問題を回避するため、アップグレード後にシステムで ANALYZE を実行してください。
Amazon RDS の PostgreSQL DB エンジンのアップグレード - Amazon Relational Database Serviceより

自分は問題発生当時、 VACUUM FULL ANALYZE をフル実行してしまったのですが、どうやら このドキュメントを見ると、ANALYZE コマンド単体で実行するだけでも大丈夫だったみたいです。

ということで、PostgreSQLのメジャーバージョンをアップグレードしたら忘れずにANALYZE コマンドを実行するようにしましょう。

以上、PostgreSQLのVACUUMANALYZEコマンドについての話でした。



CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。