sql >> Databasteknik >  >> RDS >> PostgreSQL

Bästa sättet att få resultaträkning innan LIMIT tillämpades

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.

  1. WHERE klausul (och JOIN 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.

  1. Fönsterfunktioner tillämpas beroende på OVER klausul och ramspecifikationen för funktionen. Den enkla count(*) OVER() baseras på alla kvalificerande rader.

  2. ORDER BY

( 6. DISTINCT eller DISTINCT ON skulle gå hit.) Inte här.

  1. 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


  1. 4 Out-of-the-box SQL-datakonverteringsmetoder och användningsfall

  2. Skapa en Schema Bound View i SQL Server

  3. utl_file.fopen Parametrar i Oracle

  4. SQL Server v.Next:STRING_AGG() prestanda