Функция в WHERE убивает индекс

Год из даты выглядит невинным условием:

SELECT * FROM receipts
WHERE strftime('%Y', date) = '1983';

На маленькой таблице незаметно. На большой — запрос вдруг ползёт, хотя на дату стоит индекс и он должен был помочь.

«Индекс не отвернулся сам. Функция на колонке в WHERE закрыла ему глаза — считать приходится заново для каждой строки, будто индекса и нет.»

Что именно закрыло индексу глаза?

Любая функция, обёрнутая вокруг индексируемой колонки, лишает индекс возможности сразу перейти к нужному месту — база вынуждена обойти таблицу целиком и уже потом фильтровать.

Лечение — не звать функцию на колонку, а переписать условие диапазоном: та же дата, но без обёртки.

SELECT * FROM receipts
WHERE date >= '1983-01-01'
  AND date <  '1984-01-01';
-- индекс снова видит нетронутую колонку
«Ищите не „что вычисляет запрос“, а „трогает ли он колонку функцией до сравнения“. Это и есть разница между секундой и минутой.»

Медленный запрос в архиве стоит вам минуты. На работе — куда дороже. Тренируйтесь здесь.

$0
тащи карточки за верхнюю кромку · «+ стикер» · «🧵 нить» — клик по двум

ЛОТОК УЛИК

во вкладке SQL найди подозреваемых и жми «+ доска»

НА ПРОВЕРКУ

теории из «Заметок» отправляются сюда — подтверди на доске или удали
Ctrl+Enter · «+ доска» на строке — выбрать поля и перенестипиши запрос, я подожду
Результат появится здесь.

Картотека

Заметки

Факты

Теории на проверку

Подсказки

◆ РЕЖИМ АРХИВАРИУСАуправление картотекой дел · не виден игроку