Я только что изменил мою базу данных, чтобы использовать partitioning в Postgres 8.2. Теперь у меня проблема с производительностью запросов:
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: У меня включено ограничение ограничения (спасибо @Vinko Vrsalovic)