Ren SQL
Saker och ting har förändrats sedan 2008. Du kan använda en fönsterfunktion för att få hela antalet och det begränsade resultatet i en fråga. Introducerades med PostgreSQL 8.4 2009.
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
Observera att detta kan vara betydligt dyrare än utan totalräkningen . Alla rader måste räknas, och en eventuell genväg som tar bara de översta raderna från ett matchande index kanske inte är till hjälp längre.
Det spelar ingen roll med små tabeller eller full_count
<=OFFSET
+ LIMIT
. Viktigt för ett betydligt större full_count
.
Hörnfodral :när OFFSET
är minst lika stort som antalet rader från basfrågan, ingen rad returneras. Så du får heller ingen full_count
. Möjligt alternativ:
- Kör en fråga med en LIMIT/OFFSET och få det totala antalet rader
Händelsesekvens i en SELECT
fråga
( 0. CTE:er utvärderas och materialiseras separat. I Postgres 12 eller senare kan planeraren infoga sådana som underfrågor innan de går till jobbet.) Inte här.
WHERE
klausul (ochJOIN
villkor, men inga i ditt exempel) filtrerar kvalificerande rader från bastabellen/tabellerna. Resten baseras på den filtrerade delmängden.
( 2. GROUP BY
och aggregerade funktioner skulle gå hit.) Inte här.
( 3. Annat SELECT
listuttryck utvärderas baserat på grupperade / aggregerade kolumner.) Inte här.
-
Fönsterfunktioner tillämpas beroende på
OVER
klausul och ramspecifikationen för funktionen. Den enklacount(*) OVER()
baseras på alla kvalificerande rader. -
ORDER BY
( 6. DISTINCT
eller DISTINCT ON
skulle gå hit.) Inte här.
LIMIT
/OFFSET
tillämpas baserat på den fastställda ordningen för att välja rader att returnera.
LIMIT
/ OFFSET
blir allt mer ineffektivt med ett växande antal rader i tabellen. Överväg alternativa tillvägagångssätt om du behöver bättre prestanda:
- Optimera sökfrågan med OFFSET på stora bord
Alternativ för att få slutlig räkning
Det finns helt olika metoder för att få räkningen av berörda rader (inte hela räkningen före OFFSET
&LIMIT
tillämpades). Postgres har intern bokföring hur många rader som påverkades av det senaste SQL-kommandot. Vissa klienter kan komma åt den informationen eller räkna rader själva (som psql).
Du kan till exempel hämta antalet berörda rader i plpgsql omedelbart efter att ha kört ett SQL-kommando med:
GET DIAGNOSTICS integer_var = ROW_COUNT;
Detaljer i manualen.
Eller så kan du använda pg_num_rows
i PHP . Eller liknande funktioner i andra klienter.
Relaterat:
- Beräkna antalet rader som påverkas av batchfråga i PostgreSQL