Сколько записей придется обработать при offset миллион и limit десять
Что проверяют
Знаете ли вы, что offset это не прыжок, а отсчёт. Ответ арифметический: база прочитает миллион строк, отбросит их и вернёт следующие десять, то есть обработает миллион с лишним ради десяти отданных. Дальше интервьюера интересует, чем вы это замените.
Как отвечать
Назовите цифру и объясните механику: у строки в таблице нет позиционного адреса, по которому можно сразу встать на миллионную. Даже когда порядок обеспечен индексом, движок идёт по нему и считает строки одну за другой. Стоимость растёт линейно с номером страницы, поэтому первая летает, а последние отваливаются по таймауту. Проверяется это планом запроса: в explain analyze видно, сколько строк реально прочитано.
Рабочая замена это пагинация по ключу: вместо номера страницы запоминаем последнюю отданную строку и просим следующие за ней.
const q = `select id, created_at, title from jobs
where (created_at, id) < ($1, $2)
order by created_at desc, id desc limit $3`
rows, err := db.QueryContext(ctx, q, cur.CreatedAt, cur.ID, limit+1)Условие обязано совпадать с составным индексом по тем же колонкам и в том же порядке, тогда стоимость страницы перестаёт зависеть от её номера. Курсор отдавайте наружу непрозрачной строкой, а limit+1 избавляет от отдельного count: лишняя строка означает, что следующая страница есть.
Где спотыкаются
Считают, что индекс решает проблему offset. Индекс убирает сортировку, но отсчёт пропускаемых строк остаётся, и на глубоких страницах именно он съедает время.
Второе: переходят на пагинацию по ключу, но сортируют по неуникальному полю, например только по дате создания. На границе страниц строки с одинаковой датой начинают теряться и повторяться. Лечится добавлением уникального поля вторым ключом сортировки, как в примере выше.
Третье: оставляют select count(*) на каждый запрос страницы, и он оказывается дороже самой выборки. Для ленты достаточно признака «есть ещё», а для интерфейса с номерами страниц обычно годится приблизительная оценка из статистики таблицы.