Kursory są rozsądnym wyborem do stronicowania w mniejszych aplikacjach intranetowych, które pracują z dużymi zestawami danych, ale musisz być przygotowany na odrzucenie ich po przekroczeniu limitu czasu. Użytkownicy lubią wędrować, chodzić na lunch, wyjeżdżać na dwutygodniowe wakacje itp. i pozostawiać uruchomione aplikacje. Jeśli jest to aplikacja internetowa, pojawia się nawet pytanie, czym jest „uruchomienie” i jak stwierdzić, czy użytkownik nadal jest w pobliżu.
Nie nadają się do aplikacji na dużą skalę z dużą liczbą klientów i klientów, które pojawiają się i znikają niemal losowo, jak w aplikacjach internetowych lub internetowych interfejsach API. Nie polecałbym używania kursorów w twojej aplikacji, chyba że masz dość małą liczbę klientów i bardzo wysokie stawki żądań ... w takim przypadku wysyłanie małych partii wierszy będzie bardzo nieefektywne i powinieneś zamiast tego pomyśleć o zezwoleniu na żądania zakresu itp.
Kursory mają kilka kosztów. Jeśli kursor nie jest WITH HOLD
musisz zachować otwartą transakcję. Otwarta transakcja może uniemożliwić prawidłowe działanie autovacuum, powodując rozdęcie tabeli i inne problemy. Jeśli kursor jest zadeklarowany WITH HOLD
a transakcja nie jest utrzymywana w stanie otwartym, musisz ponieść koszty materializacji i przechowywania potencjalnie dużego zbioru wyników — przynajmniej myślę, że tak działają kursory wstrzymania. Alternatywa jest równie zła, utrzymując transakcję niejawnie otwartą, dopóki kursor nie zostanie zniszczony i zapobiegając czyszczeniu wierszy.
Dodatkowo, jeśli używasz kursorów, nie możesz przekazać połączeń z powrotem do puli połączeń. Będziesz potrzebować jednego połączenia na klienta. Oznacza to, że więcej zasobów zaplecza jest używanych tylko do utrzymywania stanu sesji i ustala bardzo realny górny limit liczby klientów, z którymi można obsłużyć za pomocą podejścia opartego na kursorze.
Istnieje również złożoność i obciążenie związane z zarządzaniem stanową konfiguracją opartą na kursorze w porównaniu z bezstanowym podejściem do puli połączeń z limitem i przesunięciem. Musisz, aby Twoja aplikacja wygasała kursory po upływie limitu czasu lub napotkasz potencjalnie nieograniczone wykorzystanie zasobów na serwerze, a także musisz śledzić, które połączenia mają które kursory, dla jakich zestawów wyników dla jakich użytkowników....
Ogólnie, mimo że może to być dość nieefektywne, LIMIT
i OFFSET
może być lepszym rozwiązaniem. Często lepiej jest przeszukać klucz podstawowy zamiast używać OFFSET
jednak.
Przy okazji, przeglądałeś dokumentację dotyczącą kursorów w PL/pgSQL. Potrzebujesz do tego zadania normalnych kursorów SQL.
Czy kursory wymagają pozostawienia otwartego połączenia z bazą danych?
Tak.
Czy kursory działają wewnątrz transakcji, blokując zasoby, dopóki nie zostaną „zamknięte”?
Tak, chyba że są WITH HOLD
, w takim przypadku zużywają inne zasoby bazy danych.
Czy są jakieś inne „niespodzianki”, o których nie wiem?
Tak, jak powyższe powinno wyjaśniać.