Как я могу использовать индекс для секционированной таблицы в postgresql 8.3.7 - PullRequest
4 голосов
/ 17 июня 2009

У меня есть ситуация, когда при выполнении запроса, который фильтрует по индексируемому столбцу в многораздельной таблице, выполняется полное сканирование таблицы.

По-видимому, это известная проблема в postgresql, и она подробно объяснена здесь .

Есть ли более элегантный способ обойти это, кроме выполнения запроса для каждого раздела и последующего выполнения UNION для всех результатов?

1 Ответ

10 голосов
/ 21 июня 2009

Индексы прекрасно работают для сканирования только соответствующих разделов в PostgreSQL. Но вы должны все настроить правильно, чтобы это работало, и легко пропустить шаг в длинном списке вещей, задокументированных в http://www.postgresql.org/docs/current/static/ddl-partitioning.html

Главное, что нужно понять, это то, что для того, чтобы избежать последовательного сканирования, вы должны предоставить достаточно информации в PostgreSQL, чтобы он мог доказать, что некоторые разделы не могут иметь данные, которые вы ищете; затем они пропускаются как потенциальные источники результатов запроса. Статья, на которую вы ссылаетесь, указывает на это как на решение проблемы сканирования seq: «Если вы добавите ограничения диапазона в поле даты каждого раздела, этот запрос может быть оптимизирован в цикл, где вы сначала запрашиваете« последний »раздел и работаете в обратном направлении, пока вы не найдете единственное значение, которое превышает диапазон всех остальных разделов. "- но не показывает улучшенный план, который вы увидите после этого изменения.

Некоторые распространенные ошибки, которые вы могли совершить:

- Параметр constraint_exclusion в файле postgresql.conf по умолчанию отключен. С этим значением по умолчанию вы не получите то, что ожидаете.

-Не создавайте неперекрывающиеся разделы, используя CHECK, который не дает планировщику узнать, что находится внутри каждого из них. Можно пропустить этот шаг, но все же правильно перенести данные в нужные разделы, планировщик просто не узнает об этом.

-Не ставил индекс для каждого раздела, только создавал индекс в основной таблице. Это даст вам последовательное сканирование только на соответствующем разделе, поэтому не так плохо, как выше, но и не хорошо.

Существует некоторая работа, чтобы упростить все это в будущих выпусках PostgreSQL (настройка constraint_partition довольно автоматическая в 8.4, и в настоящее время проводится некоторая автоматизация настройки разделов). Прямо сейчас, если вы будете тщательно следовать инструкциям и избегать всех этих проблем, это должно сработать.

...