Выбор ответа Middle SELECT и фильтрация спрашивают часто обновлено

Почему тормозит большой OFFSET

Вопрос

Запрос SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 500000 выполняется секунды, хотя по id есть индекс. Почему?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: База всё равно перебирает и выбрасывает 500 000 строк. OFFSET не умеет «прыгнуть» на нужную позицию: база проходит индекс по порядку и отбрасывает первые 500 000 строк, работа растёт линейно с номером страницы.

Варианты ответа

  1. База всё равно перебирает и выбрасывает 500 000 строкправильный ответ
  2. Индекс не используется вместе с LIMIT и OFFSET
  3. OFFSET заставляет сортировать таблицу на диске каждый раз
  4. PostgreSQL кеширует только первые 1000 строк результата

Разбор

OFFSET не умеет «прыгнуть» на нужную позицию: база проходит индекс по порядку и отбрасывает первые 500 000 строк, работа растёт линейно с номером страницы. Индекс используется, сортировка не нужна, а кеша «первых строк результата» нет. Лечится keyset-пагинацией: WHERE id > последний_id ORDER BY id LIMIT 20.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.