Існує три способи отримати подібний підрахунок, кожен з яких має свої компроміси.
Якщо ви хочете справжнього рахунку, вам слід виконати оператор 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;