Ren SQL
Tingene har ændret sig siden 2008. Du kan bruge en vinduesfunktion til at få det fulde antal og det begrænsede resultat i én forespørgsel. Introduceret med PostgreSQL 8.4 i 2009.
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
Bemærk, at dette kan være betydeligt dyrere end uden det samlede antal . Alle rækker skal tælles, og en eventuel genvej, der kun tager de øverste rækker fra et matchende indeks, er muligvis ikke nyttig længere.
Betyder ikke meget med små tabeller eller full_count
<=OFFSET
+ LIMIT
. Det er vigtigt for et væsentligt større full_count
.
Hjørnehus :når OFFSET
er mindst lige så stort som antallet af rækker fra basisforespørgslen, ingen række er returneret. Så du får heller ingen full_count
. Muligt alternativ:
- Kør en forespørgsel med en LIMIT/OFFSET og få også det samlede antal rækker
Rækkefølge af hændelser i en SELECT
forespørgsel
( 0. CTE'er evalueres og materialiseres separat. I Postgres 12 eller senere kan planlæggeren inline sådanne som underforespørgsler, før de går på arbejde.) Ikke her.
WHERE
klausul (ogJOIN
betingelser, selvom ingen i dit eksempel) filtrerer kvalificerende rækker fra basistabellen/-tabellerne. Resten er baseret på den filtrerede delmængde.
( 2. GROUP BY
og aggregerede funktioner ville gå her.) Ikke her.
( 3. Andet SELECT
listeudtryk evalueres baseret på grupperede / aggregerede kolonner.) Ikke her.
-
Vinduesfunktioner anvendes afhængigt af
OVER
klausul og rammespecifikationen for funktionen. Den simplecount(*) OVER()
er baseret på alle kvalificerende rækker. -
ORDER BY
( 6. DISTINCT
eller DISTINCT ON
ville gå her.) Ikke her.
LIMIT
/OFFSET
anvendes baseret på den etablerede rækkefølge for at vælge rækker, der skal returneres.
LIMIT
/ OFFSET
bliver mere og mere ineffektiv med et stigende antal rækker i tabellen. Overvej alternative tilgange, hvis du har brug for bedre ydeevne:
- Optimer forespørgsel med OFFSET på stor tabel
Alternativer til at få den endelige optælling
Der er helt forskellige tilgange til at få optællingen af berørte rækker (ikke det fulde antal før OFFSET
&LIMIT
blev anvendt). Postgres har intern bogføring, hvor mange rækker der blev påvirket af den sidste SQL-kommando. Nogle klienter kan selv få adgang til denne information eller tælle rækker (som psql).
For eksempel kan du hente antallet af berørte rækker i plpgsql umiddelbart efter udførelse af en SQL-kommando med:
GET DIAGNOSTICS integer_var = ROW_COUNT;
Detaljer i manualen.
Eller du kan bruge pg_num_rows
i PHP . Eller lignende funktioner i andre klienter.
Relateret:
- Beregn antallet af rækker, der er påvirket af batchforespørgsel i PostgreSQL