Reines SQL
Die Dinge haben sich seit 2008 geändert. Sie können eine Fensterfunktion verwenden, um die vollständige Anzahl zu erhalten und das begrenzte Ergebnis in einer Abfrage. Eingeführt mit PostgreSQL 8.4 im Jahr 2009.
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
Beachten Sie, dass dies erheblich teurer sein kann als ohne die Gesamtzählung . Alle Zeilen müssen gezählt werden, und eine mögliche Abkürzung, die nur die obersten Zeilen aus einem passenden Index nimmt, ist möglicherweise nicht mehr hilfreich.
Spielt bei kleinen Tabellen oder full_count keine große Rolle <=OFFSET + LIMIT . Wichtig für einen wesentlich größeren full_count .
Eckfall :wenn OFFSET mindestens so groß ist wie die Anzahl der Zeilen aus der Basisabfrage, keine Zeile ist zurück gekommen. Sie erhalten also auch kein full_count . Mögliche Alternative:
- Führen Sie eine Abfrage mit einem LIMIT/OFFSET aus und erhalten Sie auch die Gesamtzahl der Zeilen
Abfolge von Ereignissen in einem SELECT Abfrage
( 0. CTEs werden separat ausgewertet und materialisiert. In Postgres 12 oder höher kann der Planer solche wie Unterabfragen einbetten, bevor er an die Arbeit geht.) Nicht hier.
WHERE-Klausel (undJOINBedingungen, obwohl keine in Ihrem Beispiel) qualifizierende Zeilen aus der/den Basistabelle(n) filtern. Der Rest basiert auf der gefilterten Teilmenge.
( 2. GROUP BY und Aggregatfunktionen würden hierher gehören.) Nicht hier.
( 3. Sonstiges SELECT Listenausdrücke werden basierend auf gruppierten / aggregierten Spalten ausgewertet.) Nicht hier.
-
Fensterfunktionen werden abhängig vom
OVERangewendet -Klausel und die Rahmenspezifikation der Funktion. Das einfachecount(*) OVER()basiert auf allen qualifizierten Zeilen. -
ORDER BY
( 6. DISTINCT oder DISTINCT ON würde hier hingehen.) Nicht hier.
LIMIT/OFFSETwerden basierend auf der festgelegten Reihenfolge angewendet, um Zeilen für die Rückgabe auszuwählen.
LIMIT / OFFSET wird mit zunehmender Anzahl von Zeilen in der Tabelle zunehmend ineffizient. Erwägen Sie alternative Ansätze, wenn Sie eine bessere Leistung benötigen:
- Optimieren Sie die Abfrage mit OFFSET für große Tabellen
Alternativen, um die endgültige Anzahl zu erhalten
Es gibt völlig unterschiedliche Ansätze, um die Anzahl der betroffenen Zeilen zu ermitteln (nicht die volle Zählung vor OFFSET &LIMIT wurden angewendet). Postgres hat eine interne Buchhaltung, wie viele Zeilen vom letzten SQL-Befehl betroffen waren. Einige Clients können auf diese Informationen zugreifen oder Zeilen selbst zählen (wie psql).
Beispielsweise können Sie die Anzahl der betroffenen Zeilen in plpgsql abrufen unmittelbar nach Ausführung eines SQL-Befehls mit:
GET DIAGNOSTICS integer_var = ROW_COUNT;
Details im Handbuch.
Oder Sie können pg_num_rows verwenden in PHP . Oder ähnliche Funktionen in anderen Clients.
Verwandte:
- Berechnen Sie die Anzahl der Zeilen, die von der Stapelabfrage in PostgreSQL betroffen sind