> Какие стратегии пагинации можно использовать вместо LIMIT OFFSET? (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: InDrive

Стек: Go

> Пример ответа

Вместо LIMIT OFFSET, которая становится неэффективной на больших смещениях (база данных всё равно сканирует все пропущенные строки), в Go-проектах часто применяют:

  1. Cursor-based пагинация (keyset pagination) - использует уникальное сортируемое поле (например, id или created_at). Вместо OFFSET передаётся значение последнего элемента предыдущей страницы. Пример запроса:

    SQL
    SELECT id, name, created_at
    FROM users
    WHERE created_at < $1 -- или id < $1 для монотонного id
    ORDER BY created_at DESC
    LIMIT $2

    В Go это реализуется передачей курсора (например, закодированного в base64) в параметрах запроса. Плюсы: константная скорость независимо от номера страницы, стабильность при вставках/удалениях. Минусы: сложнее реализовать произвольный переход на страницу.

  2. Seek method - разновидность курсорной пагинации, где курсор - это составной ключ (например, (rating, id)). Позволяет эффективно сортировать по нескольким полям:

    SQL
    SELECT * FROM products
    WHERE (rating, id) < ($1, $2)
    ORDER BY rating DESC, id DESC
    LIMIT $3
  3. Page-based с использованием индексов - если OFFSET неизбежен, можно хранить в кеше (Redis) маппинг "номер страницы → значение ключа для курсора" и пересчитывать его фоновыми задачами.

  4. Гибридный подход - для первых страниц использовать LIMIT OFFSET (они дёшевы), а для глубоких - переключаться на курсорную пагинацию.

В Go удобно реализовать курсорную пагинацию через структуру:

GO
type Cursor struct {
Value interface{} // последнее значение поля сортировки
IsAfter bool // направление
}

И передавать её в репозиторий, который строит WHERE условие.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью