Перейти к содержимому
Максиметер

Один SQL-запрос выполнялся за 298 мс.

Один SQL-запрос выполнялся за 298 мс. Почти такой же - за 0,66 мс. Разница в 451 раз из-за одной строки. Ситуация обычная: cursor pagination, сортировка по date DESC, id DESC, лимит на 1000 записей и composite index по (date, id). На первый взгляд, все должно работать быстро. Но EXPLAIN ANALYZE показывает другое: Postgres вроде бы использует Index Scan, но после этого выкидывает 900 000 строк через Filter. То есть индекс есть, но запрос все равно тащит слишком много лишнего. Проблема в условии: `date < @date OR (date = @date AND id <= @lastId)` Для разработчика это выглядит логично: сначала сравниваем дату, потом id. Но для оптимизатора такой OR плохо ложится на composite index. В итоге база не может сразу пойти по нужному диапазону и вынуждена фильтровать огромный кусок данных. Правильнее записать условие через tuple comparison: `(date, id) <= (@date, @lastId)` Смысл тот же, но для Postgres это уже понятный диапазон по составному индексу. И результат: 298 мс превращаются в 0,66 мс. Индекс сам по себе ничего не гарантирует. Важно не только создать индекс, но и написать запрос так, чтобы оптимизатор реально смог его использовать.

282 просмотров

Канал в каталоге Максиметера

3 650 подписчиков · IT и технологии

Читать дальше

Два раза в неделю свежие посты этого канала — на почту и в личную ленту. Без повторного поиска канала вручную.