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

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

Компании: Reksoft

Стек: Go

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

Вместо LIMIT OFFSET в Go (и в целом в SQL) можно применять несколько стратегий, каждая из которых решает проблему падения производительности на больших смещениях и нестабильности при частых вставках.

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

    SQL
    SELECT * FROM users WHERE id > $1 ORDER BY id LIMIT $2

    В Go это реализуется через параметры запроса: db.QueryContext(ctx, query, lastID, limit). Преимущество: стабильная производительность на любом объёме данных, так как используется индекс.

  2. Seek method - вариация cursor-based, где вместо > используется комбинация полей для точного позиционирования. Например, для сортировки по (score, id):

    SQL
    SELECT * FROM users WHERE (score, id) > ($1, $2) ORDER BY score, id LIMIT $3

    В Go можно передавать кортеж как два отдельных параметра.

  3. Page-based с фиксированным ключом - если данные редко меняются, можно использовать WHERE id BETWEEN $1 AND $2 с предварительно вычисленными диапазонами. Требует знания минимального и максимального id на странице.

  4. Использование индексов с покрытием - даже при LIMIT OFFSET можно ускорить запрос, если сначала выбрать только ключи, а потом присоединить остальные данные:

    GO
    rows, _ := db.QueryContext(ctx, "SELECT id FROM users ORDER BY id LIMIT $1 OFFSET $2", limit, offset)
    // затем SELECT * WHERE id IN (...)

На практике в Go чаще всего выбирают cursor-based пагинацию из-за её предсказуемости и простоты реализации с параметризованными запросами.

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

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