PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Der beste Weg, um die Ergebnisanzahl zu erhalten, bevor LIMIT angewendet wurde

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.

  1. WHERE -Klausel (und JOIN Bedingungen, 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.

  1. Fensterfunktionen werden abhängig vom OVER angewendet -Klausel und die Rahmenspezifikation der Funktion. Das einfache count(*) OVER() basiert auf allen qualifizierten Zeilen.

  2. ORDER BY

( 6. DISTINCT oder DISTINCT ON würde hier hingehen.) Nicht hier.

  1. LIMIT / OFFSET werden 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