PostgreSQLの各テーブルのレコード数とデータ容量の概数を調べるには

PostgreSQLのレコード数を見るには SELECT COUNT(*) ... すればわかりますが、大きいテーブルですと時間がかかります。またディスク上のデータサイズはこれではわかりません。概数でいいので、レコード数とデータサイズを見るにはどうしたらよいか?

システムカタログにテーブルごとのレコード数が保存されています。データサイズはブロック数として保存されています。ブロック数にブロックのサイズを乗算すればデータサイズの概数がわかります。

まずは、PostgreSQLのブロックサイズを見ます。この値はPostgreSQL構築時のパラメータで、テーブルによらず同じ値です。

SHOW block_size;

psqlコマンドですと、次のように表示されます。

=> SHOW block_size;
 block_size 
------------
 8192
(1 row)

1ブロックが8192バイトです。

次に、pg_class という名前のシステムカタログに、テーブルごとのデータサイズなどの統計が入っていますので、それを見ます。

pg_classreltuples というカラムには、レコード数があります。

pg_classrelpages というカラムには、ディスクを占めるブロック数があります。これにブロックサイズを乗算すればバイト単位のディスク上のデータサイズになります。

いずれも実際の正確な値ではなくPostgreSQLのプランナが使用する推測値です。VACUUMコマンド、ANALYZEコマンドなどで値が更新されるようです。

pg_classrelname はテーブル名です。

次のSQLで全テーブルのサイズを確認することができます。

SELECT relpages * 8192 AS table_size, reltuples, relname FROM pg_class ORDER BY table_size DESC;

1テーブルだけ見たい場合は relname で絞ればよいです。

SELECT relpages * 8192 AS table_size, reltuples, relname FROM pg_class WHERE relname = 'sample1';
 table_size | reltuples | relname 
------------+-----------+---------
       8192 |         0 | sample1
(1 row)

テーブルサイズが大きくて2GB以上の場合はバイト単位ですと32ビットの整数に収まらずに次のようなエラーになります。

ERROR:  integer out of range

1000000で割ってMB単位にするか、もしくはデータ型を64ビット整数であるBIGINTにするとよいです。

SELECT relpages * 0.008192 AS table_size_mb, reltuples, relname FROM pg_class ORDER BY table_size_mb DESC;
SELECT relpages :: BIGINT * 8192 AS table_size, reltuples, relname FROM pg_class ORDER BY table_size DESC;

参考 51.11. pg_class - PostgreSQL 12.0文書

2020/10/26追記

データベースごとのデータ容量を見る方法も書きました。