Вступить в клуб →
средняявопросSQL и оптимизация запросов

Пагинация с OFFSET 500000 отвечает секундами

Выгрузка истории заказов идёт постранично:

SELECT id, total FROM orders ORDER BY id DESC LIMIT 20 OFFSET 500000;

Первые страницы отдаются мгновенно, к 25-тысячной странице ответ доходит до нескольких секунд. Что здесь верно?

  • СУБД проходит и отбрасывает 500 000 строк, прежде чем вернуть 20; дешевле листать по последнему увиденному значению: WHERE id < :last_id ORDER BY id DESC LIMIT 20
  • LIMIT не умеет пользоваться индексом при больших смещениях, поэтому глубокую пагинацию переписывают на оконную функцию ROW_NUMBER с фильтром по номеру строки
  • Страница слишком мелкая: основное время уходит на установление соединения и разбор запроса, поэтому при размере страницы в 500 строк время ответа на глубоких страницах падает
  • Нет индекса по id: первичный ключ индексируется не автоматически, а отдельной командой CREATE INDEX, поэтому сортировка идёт полным проходом

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела