Таблицата има първичен ключ. Възползвайте се от него.
Вместо LIMIT
и OFFSET
, направете пейджинг с филтър на първичния ключ. Вие намекнахте за това с коментара си:
Страниране с помощта на произволни числа ( Добавете „GREATER THAN ORDER BY“ към всяка заявка)
но няма нищо случайно в това как трябва да го направите.
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2
Позволете на клиента да посочи и двата параметъра, последния идентификатор, който е видял, и броя на записите за извличане. Вашият API ще трябва да има заместител, допълнителен параметър или алтернативно извикване за „извличане на първото n IDs", където се пропуска WHERE
клауза от заявката, но това е тривиално.
Този подход ще използва сравнително ефективно сканиране на индекса, за да подреди записите, като обикновено избягва сортиране или необходимостта от повторение на всички пропуснати записи. Клиентът може да реши колко реда иска наведнъж.
Този подход се различава от LIMIT
и OFFSET
подход по един ключов начин:едновременна модификация. Ако INSERT
в таблицата с клавиш по-ниско отколкото ключ, който някой клиент вече е видял, този подход изобщо няма да промени резултатите си, докато OFFSET
подход ще повтори ред. По същия начин, ако DELETE
ред с по-нисък от вече виждания идентификатор резултатите от този подход няма да се променят, докато OFFSET
ще пропусне невидим ред. Въпреки това няма разлика за таблици само за добавяне с генерирани ключове.
Ако знаете предварително, че клиентът ще иска целия набор от резултати, най-ефективното нещо, което трябва да направите, е просто да му изпратите целия набор от резултати без нищо от този бизнес за пейджинг. Точно там бих използвайте курсор. Прочетете редовете от БД и ги изпратете на клиента толкова бързо, колкото клиентът ги приеме. Този API ще трябва да зададе ограничения за това колко бавен може да бъде клиентът, за да се избегне прекомерно натоварване на бекенда; за бавен клиент вероятно бих превключил към пейджинг (както е описано по-горе) или ще прехвърля целия резултат от курсора във временен файл и ще затворя връзката с DB.
Важни предупреждения :
- Изисква
UNIQUE
ограничение /UNIQUE
индекс илиPRIMARY KEY
да бъде надежден - Различно поведение при едновременна модификация за ограничаване/отместване, вижте по-горе