sql >> Database >  >> RDS >> PostgreSQL

Postgres:tijdstempels gebruiken voor paginering

Laat me dingen herschrijven van opmerkingen tot mijn antwoord. U wilt timestamp . gebruiken typ in plaats van integer gewoon omdat het daar precies voor is ontworpen. Handmatige conversies uitvoeren tussen gehele getallen van tijdstempels en timestamp objecten is gewoon een pijn en je wint niets. En je hebt het uiteindelijk nodig voor complexere op datetime gebaseerde zoekopdrachten.

Om een ​​vraag over paginering te beantwoorden. U doet gewoon een zoekopdracht

SELECT *
FROM table_name
WHERE created < lastTimestamp
ORDER BY created DESC
LIMIT 30

Als het de eerste vraag is, stel je lastTimestamp = '3000-01-01' . in . Anders stelt u lastTimestamp = last_query.last_row.created in .

Optimalisatie

Merk op dat als de tafel groot is dan ORDER BY created DESC is mogelijk niet efficiënt (vooral als deze parallel wordt aangeroepen met verschillende bereiken). In dit geval kunt u bewegende "tijdvensters" gebruiken, bijvoorbeeld:

SELECT *
FROM table_name
WHERE
    created < lastTimestamp
    AND created >= lastTimestamp - interval '1 day'

De 1 day interval wordt willekeurig gekozen (stem het af op uw behoeften). Je kunt de resultaten ook sorteren in de app.

Als de resultaten niet leeg zijn, update je (in je app)

lastTimestamp = last_query.last_row.created

(ervan uitgaande dat u klaar bent met sorteren, anders neemt u min(last_query.row.created) )

Als de resultaten leeg zijn, herhaalt u de zoekopdracht met lastTimestamp = lastTimestamp - interval '1 day' totdat je iets ophaalt. Je moet ook stoppen als lastTimestamp wordt te laag, d.w.z. wanneer deze lager is dan een andere tijdstempel in de tabel (die vooraf moet worden opgehaald).

Dat alles is onder een aantal veronderstellingen voor inserts:

  1. new_row.created >= any_row.created en
  2. new_row.created ~ current_time
  3. De distributie van new_row.created is min of meer uniform

Aanname 1 zorgt ervoor dat paginering resulteert in consistente gegevens, terwijl aanname 2 alleen nodig is voor de standaard 3000-01-01 datum. Aanname 3 is ervoor te zorgen dat je geen grote lege gaten hebt als je veel lege zoekopdrachten moet geven.



  1. String splitsen in rijen Oracle SQL

  2. docker postgres met initiële gegevens wordt niet bewaard tijdens commits

  3. Rails:Hoe maak je een tijdkolom met tijdzone op postgres

  4. Een voorbeeldrij één voor één uit de database retourneren