【実務・中級編】 pg_stat_user_tables – PostgreSQL

「最近、クエリが遅い気がするんだけど、どこから手をつけていいか分からない……」

現場でそんな相談を受けることがよくあります。そんな時、僕がまず最初に叩くのが `pg_stat_user_tables` です。

ドキュメントを読めば載っている情報ですが、実務でどう「味付け」して読み解くかを知っているかどうかで、トラブルシューティングのスピードは劇的に変わります。今日は、PostgreSQLの運用において欠かせないこのビューと、僕が普段やっている「テーブルの健康診断」について話をしましょう。

—

なぜ `pg_stat_user_tables` が重要なのか?

一言で言えば、「データベースがテーブルとどう付き合っているか」を一番正直に教えてくれる場所だからです。

PostgreSQLは、テーブルに対してどんな読み取り(スキャン)が行われたのか、どれくらいデータが書き換わったのかを、バックグラウンドで黙々と記録しています。この統計情報は「何が起きているか」を推測するのではなく、「何が起きているか」を観測するための最高の武器なんです。

頻出する「見るべきカラム」たち

全部を暗記する必要はありません。僕が現場でパッと確認するのは以下の項目です。

  • seq_scan: テーブルフルスキャンされた回数。これが異常に多いテーブルは、インデックスが足りていない可能性大です。
  • idx_scan: インデックス経由でスキャンされた回数。
  • n_tup_ins / n_tup_upd / n_tup_del: それぞれ挿入、更新、削除の回数。
  • n_live_tup / n_dead_tup: 現在の「生きた」データ数と、「死んだ(更新・削除で不要になった)」データ数。

—

実践:僕の「お決まり」チェッククエリ

単にビューを見るだけだと数字の羅列で頭が痛くなりますよね。実務では、以下のようなクエリで「今、何が起きているか」を可視化しています。

特に最近のPostgreSQL運用で重視しているのは「デッドタプルの溜まり具合」です。

SELECT
relname AS table_name,
n_live_tup,
n_dead_tup,
— デッドタプルの割合を算出
round(n_dead_tup::numeric / nullif(n_live_tup + n_dead_tup, 0) 100, 2) AS dead_ratio,
last_autovacuum,
last_autoanalyze
FROM
pg_stat_user_tables
WHERE
(n_live_tup + n_dead_tup) > 1000 — 小さなテーブルは無視
ORDER BY
n_dead_tup DESC;

このクエリの狙い

「デッドタプル率(dead_ratio)」が高いテーブルは、Autovacuumが追いついていないか、更新頻度が激しすぎて整理が追いついていない証拠です。これ放置すると、クエリが古いゴミデータまで読み込んでしまい、パフォーマンスがガタ落ちします。

「あれ、最近あのテーブル重くない?」と思ったら、まずはこのクエリを流して「おっと、デッドタプルが30%を超えてるぞ」と特定する。これが僕のトラブルシューティングの第一歩です。

—

統計情報とどう向き合うか:先輩からのアドバイス

最後に、統計情報を扱う上での心構えを一つ。

「統計情報は嘘をつかないが、見落としはある」ということです。

例えば、`seq_scan` が多くても、そのテーブルが元々数行しかない小さなマスタデータなら全く問題ありません。逆に、数百万行あるテーブルで `seq_scan` が1回でも走っていたら、それは「いつか大きな障害になる種」かもしれません。

数字そのものを見るのではなく、「アプリの仕様上、このテーブルはどれくらいの頻度でアクセスされるべきか?」というビジネス側の文脈を重ね合わせて見てください。

  • 「このマスタは参照しかしないはずなのに、なんで `n_tup_upd` が増えてるんだ?」
  • 「特定の期間だけ `seq_scan` が跳ね上がるのは、あのバッチ処理の影響か?」

こういう「違和感」に気づけるようになると、データベースエンジニアとしての腕はグッと上がります。

—

もし皆さんの現場で「なんとなく重い」という謎の不調に悩まされているなら、まずは `pg_stat_user_tables` を覗いてみてください。PostgreSQLは、きっとあなたの質問に対して、統計情報という形で答えを返してくれるはずですよ。

それでは、また次回の記事でお会いしましょう。良いチューニングライフを!

コメント

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