Задать вопрос
@vanillathunder

Как оптимизировать пагинацию отсортированных по времени создания записей?

Нужно сделать пагинацию по большой таблице, записи должны быть отсортированные по дате создания. В качестве id используются UUID:V4

Запрос с limit offset работает медленнее с каждой страницей из-за деградации.
Запрос вида
select * from table where id > n order by id limit 1000

Не подходит, так как нужна сортировка по дате создания и используется случайный uuid
  • Вопрос задан
  • 285 просмотров
Подписаться 1 Сложный 8 комментариев
Пригласить эксперта
Ответы на вопрос 3
OrlovEvgenii
@OrlovEvgenii
golang developer / DevOps
Можно использовать альтернативный подход, который называется "ключевая пагинация" (keyset pagination). Вместо использования offset/limit, вы будете использовать значения последнего элемента на предыдущей странице для запроса следующей страницы данных.

Для этог нужно добавить индекс на столбец с датой создания в вашей таблице, если его еще нет:
CREATE INDEX idx_created_at ON your_table_name (created_at);


Запрос
SELECT * FROM table_name
WHERE created_at < (SELECT created_at FROM table_name WHERE id = :last_id)
ORDER BY created_at DESC
LIMIT 1000;

Здесь :last_id - это идентификатор последней записи на предыдущей странице.
Ответ написан
ipatiev
@ipatiev
Потомок старинного рода Ипатьевых-Колотитьевых
Ну, вариант "в лоб" это
select * from table where date >= n and id not in (...) order by date limit 1000

где n - это последняя дата с предыдущей страницы, а ... - это список id на ту же дату с той же страницы.

Но как правильно пишут в комментариях, если пагинация начинает тормозить, то надо что-то в консерватории менять. И например разбивать не по 1000 строк, а по дате.
Ответ написан
@Jack444
Просто сделать такой индекс.
CREATE INDEX dtidx ON table (id, created DESC);
И всё, запрос будет искать id в первичном индексе, как найдёт там будет уже список таймштампов отсортированных по убыванию сделать по ним offset/limit вообще не чего не стоющая операция, ORDER BY писать уже не обязательно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы