Курсорите са разумен избор за пейджинг в по-малки интранет приложения, които работят с големи набори от данни, но трябва да сте готови да ги изхвърлите след изтичане на времето. Потребителите обичат да се скитат, да ходят на обяд, да отидат на почивка за две седмици и т.н. и да оставят приложенията си да работят. Ако това е уеб-базирано приложение, има дори въпросът какво е „работенето“ и как да се разбере дали потребителят все още е наоколо.
Те не са подходящи за широкомащабни приложения с голям брой клиенти и клиенти, които идват и си отиват почти произволно, както в уеб-базирани приложения или уеб API. Не бих препоръчал използването на курсори във вашето приложение, освен ако нямате сравнително малък брой клиенти и много висока честота на заявки... в този случай изпращането на малки партиди от редове ще бъде много неефективно и вместо това трябва да помислите за разрешаване на заявки за диапазон и т.н.
Курсорите имат няколко разходи. Ако курсорът не е WITH HOLD
трябва да държите транзакцията отворена. Отворената транзакция може да попречи на автоматичното вакуумиране да върши работата си правилно, причинявайки раздуване на масата и други проблеми. Ако курсорът е деклариран WITH HOLD
и транзакцията не е отворена, трябва да платите разходите за материализиране и съхраняване на потенциално голям набор от резултати - поне мисля, че така работят курсорите за задържане. Алтернативата е също толкова лоша, като поддържа транзакцията имплицитно отворена, докато курсорът не бъде унищожен и предотвратява изчистването на редовете.
Освен това, ако използвате курсори, не можете да предавате връзки обратно към пула за връзки. Ще ви трябва една връзка на клиент. Това означава, че повече ресурси на бекенда се използват само за поддържане на състоянието на сесията и задава много реална горна граница за броя на клиентите, с които можете да работите с подход, базиран на курсора.
Има също така сложността и режийните разходи за управление на настройка, базирана на състоянието, базирана на курсор, в сравнение с подхода за обединяване на връзки без състояние с ограничение и изместване. Трябва да имате курсори за изтичане на приложението ви след изтичане на времето или сте изправени пред потенциално неограничено използване на ресурси на сървъра и трябва да следите кои връзки имат кои курсори за кои набори от резултати за кои потребители....
Като цяло, въпреки факта, че може да бъде доста неефективно, LIMIT
и OFFSET
може да бъде по-доброто решение. Често може да е по-добре да търсите в първичния ключ, вместо да използвате OFFSET
, все пак.
Между другото, вие разглеждахте документацията за курсори в PL/pgSQL. Искате нормални курсори на ниво SQL за тази задача.
Курсорите изискват ли връзката към базата данни да бъде оставена отворена?
Да.
Курсорите работят ли вътре в транзакция, заключвайки ресурси, докато не бъдат „затворени“?
Да, освен ако не са WITH HOLD
, като в този случай те консумират други ресурси на базата данни.
Има ли други "проблеми", за които не съм наясно?
Да, както трябва да обясни горното.