sql >> Database >  >> RDS >> PostgreSQL

Cursors gebruiken voor paging in PostgreSQL

Cursors zijn een redelijke keuze voor paging in kleinere intranettoepassingen die met grote datasets werken, maar u moet bereid zijn ze na een time-out weg te gooien. Gebruikers houden ervan om rond te dwalen, te lunchen, twee weken op vakantie te gaan, enz. en hun applicaties te laten draaien. Als het een webgebaseerde app is, is er zelfs de vraag wat 'hardlopen' is en hoe je kunt zien of de gebruiker er nog is.

Ze zijn niet geschikt voor grootschalige toepassingen met een hoog aantal klanten en clients die bijna willekeurig komen en gaan, zoals in webgebaseerde apps of web-API's. Ik zou het gebruik van cursors in uw toepassing niet aanbevelen, tenzij u een vrij klein aantal klanten heeft en zeer hoge verzoeksnelheden ... in welk geval het verzenden van kleine batches rijen zeer inefficiënt zal zijn en u in plaats daarvan moet overwegen om bereikverzoeken toe te staan.

Cursors hebben verschillende kosten. Als de cursor niet WITH HOLD . is u moet een transactie openhouden. De open transactie kan voorkomen dat autovacuum zijn werk goed doet, waardoor een opgeblazen gevoel en andere problemen ontstaan. Als de cursor is gedeclareerd WITH HOLD en de transactie wordt niet opengehouden, je moet de kosten betalen voor het materialiseren en opslaan van een potentieel grote resultatenset - althans, ik denk dat dat is hoe hold-cursors werken. Het alternatief is net zo slecht, de transactie impliciet open houden totdat de cursor wordt vernietigd en voorkomen dat rijen worden opgeschoond.

Bovendien, als u cursors gebruikt, kunt u verbindingen niet teruggeven aan een verbindingspool. Je hebt één aansluiting per klant nodig. Dat betekent dat er meer backend-bronnen worden gebruikt om alleen de sessiestatus te behouden, en stelt een zeer reële bovengrens in voor het aantal clients dat u aankan met een op een cursor gebaseerde benadering.

Er is ook de complexiteit en overhead van het beheer van een stateful, cursorgebaseerde setup in vergelijking met een stateless verbindingspooling-aanpak met limiet en offset. U moet ervoor zorgen dat de cursors van uw toepassing na een time-out verlopen, anders wordt u geconfronteerd met potentieel onbeperkt gebruik van bronnen op de server, en u moet bijhouden welke verbindingen welke cursors hebben voor welke resultatensets voor welke gebruikers....

In het algemeen, ondanks het feit dat het behoorlijk inefficiënt kan zijn, LIMIT en OFFSET kan de betere oplossing zijn. Het kan vaak beter zijn om de primaire sleutel te zoeken in plaats van OFFSET . te gebruiken , hoewel.

Trouwens, je keek naar de documentatie voor cursors in PL/pgSQL. U wilt normale cursors op SQL-niveau voor deze taak.

Vereisen de cursors dat een databaseverbinding open blijft?

Ja.

Lopen de cursors binnen een transactie, waardoor bronnen worden vergrendeld totdat ze "gesloten" zijn?

Ja, tenzij ze WITH HOLD . zijn , in welk geval ze andere databasebronnen gebruiken.

Zijn er nog andere "problemen" waarvan ik me niet bewust ben?

Ja, zoals het bovenstaande zou moeten uitleggen.



  1. Volgnummer toevoegen voor elk element in een groep met behulp van een SQL-query zonder tijdelijke tabellen

  2. 2 manieren om alle tabelwaardige functies in een SQL Server-database op te sommen

  3. Indexeert MySQL automatisch kolommen met externe sleutels?

  4. Interval aan tijdstempel toevoegen met Ecto Fragments