Я только что изменил мою базу данных, чтобы использовать partitioning в Postgres 8.2. Теперь у меня проблема с выполнением запросов:Эффективный запрос многораздельной таблицы Postgres
SELECT *
FROM my_table
WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
ORDER BY id DESC
LIMIT 100;
В таблице 45 миллионов строк. Перед разделением это будет использовать обратное сканирование индекса и остановить, как только он достигнет предела.
После разделения (по диапазонам time_stamp) Postgres выполняет полное сканирование индекса главной таблицы и соответствующего раздела и объединяет результаты, сортирует их, затем применяет лимит. Это происходит слишком долго.
я могу это исправить с:
SELECT * FROM (
SELECT *
FROM my_table_part_a
WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
ORDER BY id DESC
LIMIT 100) t
UNION ALL
SELECT * FROM (
SELECT *
FROM my_table_part_b
WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
ORDER BY id DESC
LIMIT 100) t
UNION ALL
... and so on ...
ORDER BY id DESC
LIMIT 100
Это работает быстро. Разделы, в которых метки времени находятся вне диапазона, даже не включены в план запроса.
Мой вопрос: есть ли какой-либо намек или синтаксис, который я могу использовать в Postgres 8.2, чтобы предотвратить запрос от планировщика полной таблицы, но все же используя простой синтаксис, который относится только к главной таблице?
В принципе, могу ли я избежать боли при динамическом построении большого запроса UNION по каждому разделу, который в настоящее время определен?
EDIT: Я constraint_exclusion включены (спасибо @Vinko Vrsalovic)
8.2? действительно? Прежде чем делать что-либо еще, вы должны рассмотреть возможность перехода на поддерживаемую (и текущую) версию Postgres (9.2 является текущей) –