Есть три способа получить такой счет, каждый со своим собственным компромиссом.
Если вам нужен истинный счет, вы должны выполнить оператор SELECT, подобный тому, который вы использовали для каждой таблицы. Это связано с тем, что PostgreSQL хранит информацию о видимости строк в самой строке, а не где-либо еще, поэтому любой точный счет может быть только относительно некоторой транзакции. Вы получаете счет того, что видит эта транзакция в тот момент, когда она выполняется. Вы можете автоматизировать это для запуска каждой таблицы в базе данных, но вам, вероятно, не нужен такой уровень точности или вы хотите ждать так долго.
Второй подход отмечает, что сборщик статистики отслеживает, сколько строк «живое» (не удалено или не устарело при последующих обновлениях) в любое время. Это значение может быть немного занижено при высокой активности, но обычно это хорошая оценка:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Это также может показать количество мертвых строк, что само по себе является интересным числом для мониторинга.
Третий способ - отметить, что системная команда ANALYZE, которая регулярно выполняется процессом автовакуума с PostgreSQL 8.3 для обновления статистики таблицы, также вычисляет оценку строки. Вы можете взять это так:
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. Для основных целей подсчета, просто чтобы увидеть, насколько большие вещи в целом, либо должны быть достаточно точными.
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 3 DESC;