Почему PostgreSQL может отменить индексирование?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему PostgreSQL может отменить индексирование?
PostgreSQL использует оптимизатор запросов на основе стоимости, который анализирует план выполнения и принимает решение использовать индекс или нет. Даже если на столбце существует индекс, база может отказаться его использовать по нескольким причинам.
Основные причины игнорирования индекса
1. Выборка большого процента строк Если оптимизатор рассчитывает, что придётся прочитать значительную часть таблицы (обычно > 10-20%), он выбирает последовательное сканирование (Sequential Scan). Это быстрее, чем многократные обращения к индексу и основной таблице.
SELECT * FROM users WHERE is_active = true;
-- Если 95% пользователей активны, Sequential Scan быстрее
2. Недостаточная статистика (ANALYZE) PostgreSQL опирается на статистику столбцов. Если таблица недавно изменилась, а ANALYZE не запускался, оптимизатор может дать неправильную оценку.
SELECT schemaname, tablename, last_analyze
FROM pg_stat_user_tables
WHERE tablename = 'users';
ANALYZE users;
3. Малая таблица Для небольших таблиц Sequential Scan проще и быстрее, чем индексированный поиск.
4. Неправильный тип индекса
- BTREE индекс плохо работает с LIKE '%pattern%'
- HASH индекс не поддерживает range queries
- GIN индекс лучше для массивов
5. Параметризованные запросы При использовании PREPARE оптимизатор может выбрать план без индекса, основываясь на усредненной стоимости.
6. Фильтрация по NULL NULL не индексируется в стандартном BTREE. Для индексирования NULL нужен фильтр: WHERE deleted_at IS NULL
Как проверить план
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'test@example.com';
Посмотри на Index Cond (условие индекса) vs Filter (дополнительная фильтрация).
Вывод
PostgreSQL выбирает Sequential Scan если это быстрее. Это нормально и означает, что оптимизатор работает правильно. Решение: регулярный ANALYZE, правильная статистика, правильный тип индекса.