На запросы в PostgreSQL нельзя ответить, просто используя информацию в индексе.Независимо от того, является ли строка видимой с точки зрения выполняемого запроса, она хранится в самой основной строке.Поэтому, когда вы добавляете индекс к чему-либо и выполняете запрос, который его использует, происходит два шага:
- Перемещение по индексу, чтобы определить, какие блоки данных используются
- Извлечение этих блоковблокирует и возвращает строки, соответствующие запросу
Поэтому возможно, что ответ на запрос с индексом может занять больше времени, чем просто переход непосредственно к блокам данных и выборка строк.Наиболее распространенный случай, когда это происходит, если вы на самом деле захватываете большую часть данных.Обычно, если используется более 20% таблицы, считается, что достаточно просто последовательно получить к ней доступ.Иногда планировщик полагает, что будет получен доступ менее чем к 20%, поэтому индекс предпочтительнее, но это не так;это один из способов добавления индекса, который может замедлить запрос.Это может быть ситуация, которую вы наблюдаете, основываясь на вашем описании - если большие диапазоны касаются большей части таблицы, чем оценки оптимизатора, использование индекса может быть чистым замедлением.
Чтобы понять этобаза данных собирает статистику по каждому столбцу в каждой таблице, чтобы определить, является ли конкретное условие WHERE достаточно избирательным для использования индекса.Идея состоит в том, что вам нужно сохранить столько блоков, не читая всю таблицу, чтобы добавление индекса ввода-вывода поверх нее все еще было чистым выигрышем.
Это вычисление может пойти не так, так что выв конечном итоге, в нескольких случаях вы выполняете больше операций ввода-вывода, чем просто прочитали таблицу напрямую.Причина большинства из них обнаруживается, если вы выполняете запрос, используя EXPLAIN ANALYZE.Если «ожидаемые» значения в сравнении с «фактическими» числами сильно отличаются, это может указывать на то, что оптимизатор имел плохую статистику в таблице.Другая возможность состоит в том, что оптимизатор только что ошибся из-за того, насколько избирателен запрос - он думал, что вернет только небольшое количество строк, но на самом деле возвращает большую часть таблицы.Здесь, опять же, лучшая статистика - нормальный способ начать работать над этим.Если вы используете PostgreSQL 8.3 или более раннюю версию, объем собранной статистики по умолчанию очень низкий.
В некоторых рабочих нагрузках также настраивается настраиваемая переменная random_page_cost, которая контролирует, где компромисс между индексом и сканированием таблицыслучается в.Это только то, что нужно учитывать после проверки статистики.См. Настройка сервера PostgreSQL , чтобы познакомиться с несколькими вещами, которые вы можете настроить здесь.