Es gibt drei Möglichkeiten, um diese Art der Zählung zu erhalten, jede mit ihren eigenen Kompromissen.
Wenn Sie eine echte Zählung wünschen, müssen Sie die SELECT-Anweisung wie die für jede Tabelle verwendete ausführen. Dies liegt daran, dass PostgreSQL die Informationen zur Zeilensichtbarkeit in der Zeile selbst und nicht irgendwo anders speichert, sodass eine genaue Zählung nur relativ zu einer Transaktion erfolgen kann. Sie erhalten eine Zählung dessen, was diese Transaktion zum Zeitpunkt ihrer Ausführung sieht. Sie könnten dies so automatisieren, dass es für jede Tabelle in der Datenbank ausgeführt wird, aber Sie benötigen wahrscheinlich nicht diese Genauigkeit oder möchten so lange warten.
Der zweite Ansatz stellt fest, dass der Statistiksammler ungefähr nachverfolgt, wie viele Zeilen zu einem beliebigen Zeitpunkt "live" sind (nicht gelöscht oder durch spätere Aktualisierungen veraltet). Dieser Wert kann bei starker Aktivität etwas abweichen, ist aber im Allgemeinen eine gute Schätzung:
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
Das kann Ihnen auch zeigen, wie viele Zeilen tot sind, was selbst eine interessante Zahl ist, die überwacht werden muss.
Die dritte Möglichkeit besteht darin, zu beachten, dass der Systembefehl ANALYZE, der ab PostgreSQL 8.3 regelmäßig vom Autovakuumprozess ausgeführt wird, um die Tabellenstatistik zu aktualisieren, auch eine Zeilenschätzung berechnet. Sie können das so greifen:
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;
Welche dieser Abfragen besser zu verwenden ist, ist schwer zu sagen. Normalerweise treffe ich diese Entscheidung basierend darauf, ob es weitere nützliche Informationen gibt, die ich auch innerhalb von pg_class oder innerhalb von pg_stat_user_tables verwenden möchte. Für grundlegende Zählzwecke sollte nur genau genug sein, um zu sehen, wie groß die Dinge im Allgemeinen sind.
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;