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;
n_live_tup
? In meiner Redshift-Datenbank fehlt diese Spalte. Es ist eine Ableitung von Postgres 8.0.2.pg_stat_user_tables
) hatn_live_tup
für mich meistens Nullen zurückgegeben , da sieANALYZE
noch nie ausgeführt wurde. AnstattANALYZE
jedes Schema / jede Tabelle auszuführen und ewig auf eine Antwort zu warten, überprüfte ich zuerst die Ergebnisse mit dem 'dritten Ansatz' und dieser (mitpg_class
) lieferte sehr genaue Zählungen.Hier ist eine Lösung, für die keine Funktionen erforderlich sind, um eine genaue Zählung für jede Tabelle zu erhalten:
query_to_xml
führt die übergebene SQL-Abfrage aus und gibt ein XML mit dem Ergebnis zurück (die Zeilenanzahl für diese Tabelle). Das Äußerexpath()
extrahiert dann die Zählinformationen aus dieser XML und konvertiert sie in eine ZahlDie abgeleitete Tabelle ist nicht wirklich notwendig, macht das aber
xpath()
etwas verständlicher - sonstquery_to_xml()
müsste das Ganze an diexpath()
Funktion übergeben werden.quelle
query_to_jsonb()
.select count(*)
auf jedem Tisch ein Fehler auftritt.xpath()
Funktion wird nur auf eine einzelne Zeile angewendet - das Ergebnis descount(*)
Schätzungen finden Sie in Greg Smiths Antwort .
Um genaue Zahlen zu erhalten, sind die anderen Antworten bisher mit einigen Problemen behaftet, von denen einige schwerwiegend sind (siehe unten). Hier ist eine Version, die hoffentlich besser ist:
Es wird ein Schemaname als Parameter verwendet oder
public
wenn kein Parameter angegeben wird.Um mit einer bestimmten Liste von Schemas oder einer Liste zu arbeiten, die aus einer Abfrage stammt, ohne die Funktion zu ändern, kann sie innerhalb einer Abfrage wie folgt aufgerufen werden:
Dies erzeugt eine 3-Spalten-Ausgabe mit dem Schema, der Tabelle und der Zeilenanzahl.
Hier sind einige Probleme in den anderen Antworten, die diese Funktion vermeidet:
Tabellen- und Schemanamen sollten nicht ohne Anführungszeichen in ausführbares SQL eingefügt werden, weder mit
quote_ident
noch mit der modernerenformat()
Funktion mit ihrer%I
Formatzeichenfolge. Andernfalls kann eine böswillige Person ihre Tabelle benennen, die als Tabellennametablename;DROP TABLE other_table
vollkommen gültig ist.Auch ohne Probleme mit der SQL-Injection und den lustigen Zeichen kann der Tabellenname in Varianten vorhanden sein, die sich von Fall zu Fall unterscheiden. Wenn eine Tabelle benannt ist
ABCD
und eine andereabcd
,SELECT count(*) FROM...
muss der Name in Anführungszeichen gesetzt werden, da er sonst zweimal übersprungenABCD
und gezähltabcd
wird. Das%I
of-Format erledigt dies automatisch.information_schema.tables
listet zusätzlich zu Tabellen benutzerdefinierte zusammengesetzte Typen auf, auch wenn table_type'BASE TABLE'
(!) ist. Infolgedessen können wir nicht weiter iteriereninformation_schema.tables
, sonst riskieren wir esselect count(*) from name_of_composite_type
und das würde fehlschlagen. OTOHpg_class where relkind='r'
sollte immer gut funktionieren.Der Typ von COUNT () ist
bigint
nichtint
. Möglicherweise sind Tabellen mit mehr als 2,15 Milliarden Zeilen vorhanden (eine Zählung (*) ist jedoch eine schlechte Idee).Es muss kein permanenter Typ erstellt werden, damit eine Funktion eine Ergebnismenge mit mehreren Spalten zurückgibt.
RETURNS TABLE(definition...)
ist eine bessere Alternative.quelle
Wenn Ihnen möglicherweise veraltete Daten nichts ausmachen, können Sie auf dieselben Statistiken zugreifen, die vom Abfrageoptimierer verwendet werden .
Etwas wie:
quelle
ANALYZE
für die Tabelle ausgeführt haben, können die Statistiken weit davon entfernt sein. Es ist eine Frage der Datenbanklast und der Konfiguration der Datenbank (wenn die Statistiken häufiger aktualisiert werden, sind die Statistiken genauer, können jedoch die Laufzeitleistung beeinträchtigen). Letztendlich besteht die einzige Möglichkeit, genaue Daten zu erhalten, darin,select count(*) from table
für alle Tabellen zu arbeiten.Die hackige, praktische Antwort für Leute, die versuchen zu bewerten, welchen Heroku-Plan sie benötigen und nicht darauf warten können, dass Herokus langsamer Zeilenzähler aktualisiert wird:
Im Grunde wollen Sie laufen
\dt
inpsql
, kopieren Sie die Ergebnisse zu Ihrem bevorzugten Texteditor (es wird wie folgt aussehen:), führen Sie dann eine Regex-Suche durch und ersetzen Sie diese wie folgt:
zu:
was Ihnen etwas sehr Ähnliches ergeben wird:
(Sie müssen das letzte entfernen
union
und das Semikolon am Ende manuell hinzufügen.)Führen Sie es ein
psql
und Sie sind fertig.quelle
select '$1', count(*) from $1 union/g
/g
(behaltenunion
) und hinzufügen;
. Vergessen Sie nicht, das letzteunion
vor dem Semikolon zu entfernen .union
vor dem Semikolon zu entfernen ", meinte ich :) Das Wort "last" wurde hinzugefügt, um dies zu verdeutlichenIch bin mir nicht sicher, ob eine Antwort in Bash für Sie akzeptabel ist, aber FWIW ...
quelle
select count(*) from table_name;
im OP auf dasselbe hinaus !Ich verlasse mich normalerweise nicht auf Statistiken, besonders in PostgreSQL.
quelle
dsql2('select count(*) from livescreen.'||table_name)
oder besser, er könnte in eine eigene Funktion umgewandelt werden.Ich erinnere mich nicht an die URL, unter der ich diese gesammelt habe. Aber hoffe das sollte dir helfen:
Durch Ausführen
select count_em_all();
sollten Sie die Zeilenanzahl aller Ihrer Tabellen erhalten.quelle
quote_ident(t_name.relname)
) anzugeben, um die ordnungsgemäße Unterstützung ungewöhnlicher Namen (z. B. "Spaltenname") sicherzustellen.SELECT * FROM count_em_all() as r ORDER BY r.num_rows DESC;
Einfache zwei Schritte:
(Hinweis: Sie müssen nichts ändern - einfach kopieren, einfügen)
1. Funktion erstellen
2. Führen Sie diese Abfrage aus, um die Zeilenanzahl für alle Tabellen abzurufen
oder
Um Zeilenzählungen tabellarisch abzurufen
quelle
Ich habe eine kleine Variation vorgenommen, um alle Tabellen einzuschließen, auch für nicht öffentliche Tabellen.
verwenden
select count_em_all();
, um es zu nennen.Ich hoffe, Sie finden das nützlich. Paul
quelle
Das hat bei mir funktioniert
quelle
Ich mag die Antwort von Daniel Vérité . Wenn Sie jedoch keine CREATE-Anweisung verwenden können, können Sie entweder eine Bash-Lösung oder, wenn Sie ein Windows-Benutzer sind, eine Powershell-Lösung verwenden:
quelle
Ich wollte die Summe aller Tabellen + eine Liste der Tabellen mit ihrer Anzahl. Ein bisschen wie ein Leistungsdiagramm, in dem die meiste Zeit verbracht wurde
Sie können natürlich auch
LIMIT
in dieser Version eine Klausel zu den Ergebnissen setzen, damit Sie die größte erhaltenn
Straftäter sowie insgesamt erhalten.Eine Sache, die dabei beachtet werden sollte, ist, dass Sie es nach Massenimporten eine Weile stehen lassen müssen. Ich habe dies getestet, indem ich einer Datenbank über mehrere Tabellen hinweg 5000 Zeilen mit echten Importdaten hinzugefügt habe. Es zeigte 1800 Datensätze für ungefähr eine Minute (wahrscheinlich ein konfigurierbares Fenster)
Dies basiert auf der Arbeit von https://stackoverflow.com/a/2611745/1548557. Vielen Dank und Anerkennung für die Abfrage, die innerhalb des CTE verwendet werden soll
quelle