Keyset-пагинация: быстрый скролл без OFFSET!
OFFSET…LIMIT прост, но плохо масштабируется: чем дальше страница, тем медленнее запрос и выше риск дубликатов при вставках.Keyset использует курсор (id/дату) и даёт стабильную скорость на больших объёмах.Создаём таблицу (пример на PostgreSQL):
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Подготавливаем входящие данные с помощью CTE:
WITH cursor AS (
SELECT 1000::BIGINT AS last_seen_id
)Здесь мы храним «курсор» — id последней записи, которую клиент уже получил.
Получаем следующую страницу без OFFSET по keyset-подходу:
SELECT p.id, p.title, p.created_at
FROM posts p
JOIN cursor c ON TRUE
WHERE p.id < c.last_seen_id
ORDER BY p.id DESC
LIMIT 20;Запрос отдаёт следующие 20 записей с
id < last_seen_id.На клиенте берём минимальный id из результата и используем его как новый
last_seen_id для следующего запроса.Подход работает в PostgreSQL, MySQL, SQL Server и др.: стабильно, эффективно и без проблем с дубликатами при конкурентных вставках.
SQL Ready | #практика
Просмотры: 415