🚀 SQL: индекс есть, но база специально его игнорирует
Есть индекс:
CREATE INDEX idx_users_status ON users(status);
И запрос:
SELECT *
FROM users
WHERE status != 'active';
Кажется, что индекс должен ускорить поиск.
Но если условие возвращает большую часть таблицы, индекс может оказаться дороже обычного Seq Scan.
Например, если 'active' — только 10% строк, то:
status != 'active'
вернёт примерно 90% таблицы.
В таком случае базе дешевле один раз последовательно прочитать таблицу, чем прыгать по индексу к огромному количеству строк.
Проверить можно так:
EXPLAIN ANALYZE
SELECT *
FROM users
WHERE status != 'active';
Смотреть нужно не только на наличие индекса, а на селективность условия.
Особенно часто это проявляется с:
NOT IN
IS NOT NULL
Индекс может быть идеальным, но если запрос выбирает почти всю таблицу, оптимизатор вполне разумно его проигнорирует.
Есть индекс:
CREATE INDEX idx_users_status ON users(status);
И запрос:
SELECT *
FROM users
WHERE status != 'active';
Кажется, что индекс должен ускорить поиск.
Но если условие возвращает большую часть таблицы, индекс может оказаться дороже обычного Seq Scan.
Например, если 'active' — только 10% строк, то:
status != 'active'
вернёт примерно 90% таблицы.
В таком случае базе дешевле один раз последовательно прочитать таблицу, чем прыгать по индексу к огромному количеству строк.
Проверить можно так:
EXPLAIN ANALYZE
SELECT *
FROM users
WHERE status != 'active';
Смотреть нужно не только на наличие индекса, а на селективность условия.
Особенно часто это проявляется с:
NOT IN
IS NOT NULL
Индекс может быть идеальным, но если запрос выбирает почти всю таблицу, оптимизатор вполне разумно его проигнорирует.