Markörer är ett rimligt val för personsökning i mindre intranätsapplikationer som fungerar med stora datamängder, men du måste vara beredd att kassera dem efter en timeout. Användare gillar att vandra iväg, äta lunch, åka på semester i två veckor, etc, och låta sina applikationer vara igång. Om det är en webbaserad app finns det till och med frågan om vad "löpning" är och hur man kan se om användaren fortfarande är kvar.
De är inte lämpliga för storskaliga applikationer med högt klientantal och klienter som kommer och går nästan slumpmässigt som i webbaserade appar eller webb-API:er. Jag skulle inte rekommendera att använda markörer i din applikation såvida du inte har ett ganska litet antal klienter och mycket höga förfrågningsfrekvenser ... i så fall kommer det att vara mycket ineffektivt att skicka små satser med rader och du bör tänka på att tillåta intervallförfrågningar etc istället.
Markörer har flera kostnader. Om markören inte är WITH HOLD
du måste hålla en transaktion öppen. Den öppna transaktionen kan förhindra autovacuum från att göra sitt arbete ordentligt, vilket orsakar uppblåst bord och andra problem. Om markören deklareras WITH HOLD
och transaktionen inte hålls öppen måste du betala kostnaden för att materialisera och lagra en potentiellt stor resultatuppsättning - åtminstone tror jag att det är så hållmarkörer fungerar. Alternativet är lika dåligt, att hålla transaktionen implicit öppen tills markören förstörs och förhindra att rader rensas upp.
Dessutom, om du använder markörer kan du inte lämna tillbaka anslutningar till en anslutningspool. Du behöver en anslutning per klient. Det betyder att fler backend-resurser används bara för att upprätthålla sessionstillståndet, och sätter en mycket verklig övre gräns för antalet klienter du kan hantera med en markörbaserad strategi.
Det finns också komplexiteten och overheaden med att hantera en tillståndsfull, markörbaserad installation jämfört med en tillståndslös anslutningspoolingmetod med limit och offset. Du måste få din applikation att förfalla markörer efter en timeout, annars möter du potentiellt obegränsad resursanvändning på servern, och du måste hålla reda på vilka anslutningar som har vilka markörer för vilka resultatuppsättningar för vilka användare...
I allmänhet, trots att det kan vara ganska ineffektivt, LIMIT
och OFFSET
kan vara den bättre lösningen. Det kan ofta vara bättre att söka efter primärnyckeln istället för att använda OFFSET
dock.
Du tittade förresten på dokumentationen för markörer i PL/pgSQL. Du vill ha normala markörer på SQL-nivå för det här jobbet.
Kräver markörerna att en databasanslutning lämnas öppen?
Ja.
Körs markörerna i en transaktion och låser resurser tills de är "stängda"?
Ja om de inte är WITH HOLD
, i vilket fall de förbrukar andra databasresurser.
Finns det några andra "gotchas" som jag inte är medveten om?
Ja, som ovanstående borde förklara.