Как я могу использовать индекс для секционированной таблицы в postgresql 8.3.7

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

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

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


person Tom Feiner    schedule 17.06.2009    source источник
comment
Также задайте вопрос в списке рассылки по производительности Postgres здесь archives.postgresql.org/pgsql-performance. .   -  person Milen A. Radev    schedule 17.06.2009
comment
Эта статья, на которую вы ссылаетесь, неверна, потому что автор не слишком хорошо знаком с разделением. Он не включил ограничение_исключения или индексы для каждого раздела.   -  person Jin Kim    schedule 24.08.2009
comment
Я не понимаю, почему индексы должны быть исключены только потому, что запрос пересекает границы раздела. В моем случае я обнаружил эту проблему, когда пытался найти очень маленький набор различных значений для столбца, который имеет индекс в каждом разделе. выберите отдельный столбец в разделе, использующем сканирование индекса. то же самое в родительской таблице выполняет полное сканирование таблицы каждого раздела, затем объединяет, затем сортирует. выбрать отдельный столбец из (выбрать объединение выбрать объединение выбрать...) НАМНОГО быстрее, чем выбрать отдельный столбец из родителя Кто-нибудь знает, почему планировщик не делает очевидное?   -  person ideasculptor    schedule 07.04.2010


Ответы (1)


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

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

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

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

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

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

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

person Greg Smith    schedule 21.06.2009