1. ホーム
  2. postgresql

[解決済み] Postgres の全テーブルの行数を求めるには?

2022-03-19 07:23:09

質問

Postgresの全テーブルの行数を調べる方法を探しています。 一度に1つのテーブルを検索することができます。

SELECT count(*) FROM table_name;

しかし、すべてのテーブルの行数を確認し、その行数で並べ替えることで、すべてのテーブルの大きさを把握したいのです。

どのように解決するのですか?

この種のカウントを得るには3つの方法があり、それぞれにトレードオフがあります。

もし、真のカウントをしたいのであれば、各テーブルに対して使用したようなSELECT文を実行する必要があります。 これは、PostgreSQLが行の可視性情報を他の場所ではなく、行自体に保持しているためです。したがって、正確なカウントは何らかのトランザクションとの相対関係でしかありえません。 つまり、トランザクションが実行された時点で、そのトランザクションが見ているものをカウントしているのです。 これをデータベース内のすべてのテーブルに対して実行するように自動化することもできますが、そのような精度は必要ないでしょうし、それほど長く待つ必要もないでしょう。

2つ目の方法は、統計情報コレクターが、いつでも何行が"live"(削除されておらず、後の更新によって陳腐化されていない)かをおおよそ追跡していることに着目するものです。 この値は、アクティビティが激しい場合には少しずれることがありますが、一般的には良い推定値となります。

SELECT schemaname,relname,n_live_tup 
  FROM pg_stat_user_tables 
  ORDER BY n_live_tup DESC;

これはまた、死んでいる行の数を示すことができ、それ自体、監視するのに興味深い数字です。

3つ目の方法は、PostgreSQL 8.3以降、テーブルの統計情報を更新するためにautovacuumプロセスによって定期的に実行されるシステムの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の内部のどちらでより有用な情報を使用したいかに基づいて決定します。 一般的にどの程度の規模であるかを確認するための基本的な集計目的であれば、どちらでも十分な精度が得られるはずです。