LoginSignup
1
2

PostgreSQLで特定のデータベースの全テーブルのレコード数をカウントする

Last updated at Posted at 2023-10-30

PostgreSQLを使っていて、「このデータベースの総レコード数って何件になる?」と聞かれることがたまにあります。
それはデータのサイズ感をデータディレクトリのサイズで言ってもピンとこなかったり、データ移行後に件数を比較するために正確な件数が知りたかったりと理由は様々あると思いますが、とにかくレコード数が知りたい。

手っ取り早く件数を調べるには以下のSQLが使えます。

SELECT reltuples FROM pg_class WHERE relname = '件数を調べたいテーブル名';

pg_classはPostgreSQLのシステムカタログ1の一つで、テーブルと、その他に列を持つもの、あるいはテーブルに似た全てのもの(インデックスやシーケンス等)の情報を格納しています。reltuples列はテーブルのタプル数、つまりレコード数を保存しています。

しかしreltuplesの値はプランナが参照する推定値であり、正確ではありません。おおよその数を知るだけなら活用できますが、「正確な現在の件数」を調べるには不向きです。

正確な現在の件数を知るためには、COUNT関数を使用します。

SELECT COUNT(*) FROM 件数を調べたいテーブル名;

確かにCOUNT関数を使用すれば正確な件数がわかりますが、複数のテーブルの件数を同時に取得することができません。大量のテーブルがある場合、まずテーブルを列挙してSELECT COUNT(*)をテーブルの数実行する必要があります。テーブルを列挙したときに漏れがあると困りますし、一個一個SQLを実行していくと時間もかかります。実行し忘れたりするかもしれません。

なんとか一発で全テーブルにもれなくSELECT文を実行できないか考え、PL/pgSQLで関数を作成することにしました。

CREATE OR REPLACE FUNCTION pg_temp.record_count()
RETURNS TABLE(objname TEXT, recordcount NUMERIC) AS $$
DECLARE
  cursor_tablename CURSOR FOR
    SELECT (schemaname || '.' || tablename) AS table_name
    FROM pg_tables
    WHERE
      schemaname !~ 'pg_*' AND
      schemaname != 'information_schema'
    ORDER BY table_name;

BEGIN

  FOR rec_table IN cursor_tablename LOOP
    EXECUTE 'SELECT COUNT(*) FROM ' || rec_table.table_name INTO recordcount;
    objname := rec_table.table_name;
    RETURN NEXT;
  END LOOP;
  RETURN;

END;
$$ LANGUAGE plpgsql;

上記PL/pgSQLを実行し、次のSQLで作成した関数を実行すると、データベース内に存在する全てのテーブルとそのテーブルの件数がどばっと表示されます。ただし「pg_」から始まるスキーマに属するテーブルと「information_schema」に属するテーブルは除外しています。

SELECT * FROM pg_temp.record_count();

テーブル数やレコード数が多いと実行に結構時間がかかります。

なお、pg_tempスキーマに作成しているため、この関数はセッションが終了すると削除されます。
これは用が済んだあとに削除し忘れないようにしているためで、残しておいて時々使いたい場合はpublicに作成してもいいかもしれません。

  1. リレーショナルデータベースがテーブルや列の情報などのスキーマメタデータと内部的な情報を格納する場所。 PostgreSQLのシステムカタログは通常のテーブルとして実装されている。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2