Я только что реструктурировал свою базу данных, чтобы использовать разбиение в 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 для каждого раздела, который в настоящее время определен?
РЕДАКТИРОВАТЬ: У меня включено ограничение_обязания (спасибо @Vinko Vrsalovic)