Пагинация с 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, поэтому сортировка идёт полным проходом
