Pagination: тест с выбором ответа
Синтез по всему юниту в формате выбора: стоимость offset против keyset, дрейф страниц при записи, стабильный ordering, opaque cursor и скрытый налог на COUNT.
Шесть вопросов на весь юнит. Ни один не про определение — каждый это решение, которое вы принимаете, проектируя реальный list-эндпоинт, обязанный пережить таблицу на 50 миллионов строк и постоянные записи.
Убедитесь, что вы связываете стоимость offset, дрейф страниц, стабильность ordering, контракт opaque cursor и налог на подсчёт — это синтез, к которому вёл урок, а не отдельные факты.
Эндпоинт выполняет LIMIT 20 OFFSET 200000 по таблице на 50M строк. Возвращает 20 строк, но занимает ~8 секунд. Почему стоимость растёт с offset, а не с размером страницы?
В быстрой ленте пользователи видят один и тот же пост дважды, а другие клянутся, что посты 'исчезли'. Фронтенд корректен, таблица маленькая. В чём причина?
Keyset-лента сортирует только по created_at DESC и несёт последний created_at как cursor. Иногда пост на стыке страниц пропускается или показывается дважды. Почему и что это исправляет?
Продукту нужны и админская таблица с 'перейти на страницу 4000 из 80000', и публичная лента с бесконечным скроллом по тем же данным. Какое решение верное?
Коллега предлагает вернуть сырой кортеж (created_at, id) как cursor, 'раз клиент всё равно просто шлёт его обратно'. Почему лучше непрозрачный (opaque) cursor?
Эндпоинт теперь быстр через keyset, но p99 всё ещё высок из-за подвала 'Показано 1–20 из 4 812 339'. Почему точный подсчёт дорог в Postgres и какой senior-ход?
Сквозная линия юнита это одно решение: адресуете страницы по позиции (offset) — платите дважды: глубокие страницы линейно делают scan-and-discard (сканирование с выбросом), а позиционные границы дрейфуют при записи в дубликаты и пропуски. Адресуете по значению (keyset) по уникальному, стабильному, индексированному ключу — задержка остаётся плоской без дрейфа, ценой потери произвольных переходов по страницам, поэтому offset всё ещё уместен на ограниченных админских таблицах. Отдавайте клиентам opaque cursor (непрозрачный курсор), чтобы контракт мог эволюционировать, и относитесь к точному итогу как к отдельному скану: оценивайте или зондируйте через LIMIT n+1 вместо подсчёта, который никому не нужен. Теперь, когда видишь list-эндпоинт с растущим p99 и жалобами на дубли, у тебя есть чеклист: проверь «actual rows» в плане, проверь уникальность ключа сортировки, проверь, непрозрачен ли курсор, и спроси — стоит ли подвал с COUNT своего скана.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.