私は Postgres のすべてのテーブルの行数を調べる方法を探しています。一度に 1 つのテーブルでこれを行うには、次の操作を実行できるとわかっています。
SELECT count(*) FROM table_name;
しかし、すべてのテーブルの行数を確認し、それに基づいて並べ替えて、すべてのテーブルの大きさを把握したいと思います。
ベストアンサー1
この種のカウントを取得するには 3 つの方法があり、それぞれにトレードオフがあります。
正確なカウントが必要な場合は、各テーブルに対して使用したのと同じ SELECT ステートメントを実行する必要があります。これは、PostgreSQL が行の可視性情報を行自体に保持し、他の場所には保持しないため、正確なカウントはトランザクションに関連しているだけです。トランザクションが実行される時点でそのトランザクションが参照するカウントを取得します。これを自動化してデータベース内のすべてのテーブルに対して実行することもできますが、おそらくそのレベルの精度は必要ないか、それほど長く待つ必要はありません。
WITH tbl AS
(SELECT table_schema,
TABLE_NAME
FROM information_schema.tables
WHERE TABLE_NAME not like 'pg_%'
AND table_schema in ('public'))
SELECT table_schema,
TABLE_NAME,
(xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', table_schema, TABLE_NAME), FALSE, TRUE, '')))[1]::text::int AS rows_n
FROM tbl
ORDER BY rows_n DESC;
2 番目のアプローチでは、統計コレクターが、いつでも「ライブ」な (削除されていない、または後の更新によって古くなった) 行の大まかな数を追跡します。この値は、アクティビティが激しい場合は少しずれることがあります。ただし、一般的には適切な推定値です。
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
また、デッド行の数も表示され、それ自体が監視する上で興味深い数値となります。
3 番目の方法は、PostgreSQL 8.3 以降、テーブル統計を更新するために自動バキューム プロセスによって定期的に実行されるシステム ANALYZE コマンドも行の推定値を計算することに注意することです。次のようにしてこれを取得できます。
SELECT
nspname AS schemaname,relname,reltuples
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE
nspname NOT IN ('pg_catalog', 'information_schema') AND
relkind='r'
ORDER BY reltuples DESC;
これらのクエリのどちらを使用するのがよいかは、一概には言えません。通常、pg_class 内または pg_stat_user_tables 内に、より有用な情報があるかどうかに基づいて決定します。一般的にどの程度大きいかを確認するための基本的なカウント目的であれば、どちらでも十分に正確です。