Выбор ответа Middle Индексы спрашивают часто обновлено

Функция над колонкой и индекс

Вопрос

На users(email) есть обычный B-tree индекс. Почему этот запрос читает всю таблицу и как это исправить?

SELECT * FROM users WHERE lower(email) = 'anna@mail.ru';

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

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

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

Коротко

Правильный ответ: Индекс по email, а не по lower(email): нужен индекс по выражению. Индекс хранит отсортированные значения email, а условие сравнивает результат функции, которого в индексе нет.

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

  1. Индекс по email, а не по lower(email): нужен индекс по выражениюправильный ответ
  2. B-tree не работает со строками; нужен hash-индекс по email
  3. Строковые сравнения всегда идут через seq scan; нужна отдельная таблица
  4. Мешает =: с LIKE по тому же выражению индекс бы сработал

Разбор

Индекс хранит отсортированные значения email, а условие сравнивает результат функции, которого в индексе нет. Индекс по выражению хранит как раз lower(email) и подходит для такого условия. B-tree прекрасно работает со строками, а hash-индекс точно так же не поможет при функции над колонкой. LIKE проблему не решает: функция над колонкой осталась бы.

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

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