sql >> Database >  >> RDS >> PostgreSQL

De beste manier om het aantal resultaten te krijgen voordat LIMIT werd toegepast

Pure SQL

Dingen zijn veranderd sinds 2008. U kunt een vensterfunctie gebruiken om de volledige telling en . te krijgen het beperkte resultaat in één zoekopdracht. Geïntroduceerd met PostgreSQL 8.4 in 2009.

SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

Merk op dat dit aanzienlijk duurder kan zijn dan zonder de totale telling . Alle rijen moeten worden geteld, en een mogelijke snelkoppeling die alleen de bovenste rijen van een overeenkomende index neemt, is misschien niet meer nuttig.
Maakt niet veel uit met kleine tabellen of full_count <=OFFSET + LIMIT . Belangrijk voor een aanzienlijk grotere full_count .

Hoekkast :wanneer OFFSET is minstens zo groot als het aantal rijen van de basisquery, geen rij wordt teruggestuurd. Je krijgt dus ook geen full_count . Mogelijk alternatief:

  • Voer een zoekopdracht uit met een LIMIT/OFFSET en verkrijg ook het totale aantal rijen

Opeenvolging van gebeurtenissen in een SELECT vraag

( 0. CTE's worden afzonderlijk geëvalueerd en gematerialiseerd. In Postgres 12 of later kan de planner dergelijke subquery's toevoegen voordat hij aan het werk gaat.) Niet hier.

  1. WHERE clausule (en JOIN voorwaarden, hoewel geen in uw voorbeeld) kwalificerende rijen filteren uit de basistabel(len). De rest is gebaseerd op de gefilterde subset.

( 2. GROUP BY en geaggregeerde functies zouden hier komen.) Niet hier.

( 3. Overige SELECT lijstexpressies worden geëvalueerd op basis van gegroepeerde/geaggregeerde kolommen.) Niet hier.

  1. Vensterfuncties worden toegepast afhankelijk van de OVER clausule en de framespecificatie van de functie. De eenvoudige count(*) OVER() is gebaseerd op alle kwalificatierijen.

  2. ORDER BY

( 6. DISTINCT of DISTINCT ON zou hierheen gaan.) Niet hier.

  1. LIMIT / OFFSET worden toegepast op basis van de vastgestelde volgorde om rijen te selecteren om terug te keren.

LIMIT / OFFSET wordt steeds inefficiënter met een groeiend aantal rijen in de tabel. Overweeg alternatieve benaderingen als u betere prestaties nodig heeft:

  • Zoekopdracht optimaliseren met OFFSET op grote tafel

Alternatieven om de definitieve telling te krijgen

Er zijn totaal verschillende benaderingen om het aantal getroffen rijen te krijgen (niet de volledige telling vóór OFFSET &LIMIT werden toegepast). Postgres heeft een interne boekhouding hoeveel rijen zijn beïnvloed door de laatste SQL-opdracht. Sommige clients hebben toegang tot die informatie of tellen zelf rijen (zoals psql).

U kunt bijvoorbeeld het aantal betrokken rijen ophalen in plpgsql onmiddellijk na het uitvoeren van een SQL-opdracht met:

GET DIAGNOSTICS integer_var = ROW_COUNT;

Details in de handleiding.

Of u kunt pg_num_rows . gebruiken in PHP . Of vergelijkbare functies in andere clients.

Gerelateerd:

  • Bereken het aantal rijen dat wordt beïnvloed door batchquery's in PostgreSQL


  1. Hoe converteer ik een geheel getal naar een string als onderdeel van een PostgreSQL-query?

  2. Zijn mysql_real_escape_string() en mysql_escape_string() voldoende voor app-beveiliging?

  3. Recursieve categorieën met een enkele zoekopdracht?

  4. Hoe SQLite-lengte() werkt