Я только что реструктурировал свою базу данных для использования разделения в Пост-ГРЭС 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), Пост-ГРЭС делает полное индексное сканирование основной таблицы и соответствующего раздела и объединяет результаты, сортирует их, затем применяет предел. Это берет слишком долго.
Я могу зафиксировать его с:
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
Это работает быстро. Разделы, где штампы времен из диапазона, даже не включены в план запросов.
Мой вопрос: Есть ли некоторая подсказка или синтаксис, который я могу использовать в Пост-ГРЭС 8.2, чтобы препятствовать тому, чтобы планировщик запроса сканировал полную таблицу, но все еще использовал простой синтаксис, который только относится к основной таблице?
В основном я могу избежать боли динамичного создания большого Запроса на объединение по каждому разделу, который, оказывается, в настоящее время определяется?
Править: У меня есть включенный constraint_exclusion (благодарит @Vinko Vrsalovic),
Пытались ли вы попробовать Исключение ограничений (раздел 5.9.4 в документе, на который вы ссылаетесь)
Исключение ограничений - запрос метод оптимизации, который улучшает производительность для таблиц разделов определённым образом наверху. В качестве примера:
SET constraint_exclusion = on;
SELECT count(*) FROM measurement WHERE logdate >= DATE '2006-01-01';
Без исключение ограничения, вышеприведенный запрос сканировал бы каждый из разделов таблицу измерений. С ограничением исключение включено, планировщик будет рассматривать ограничения каждого разделить и попытаться доказать, что раздел не нужно сканировать, потому что он не мог содержать никаких встреч рядов запрос - это пункт "ГДЕ". Когда планировщик может это доказать, это исключает раздел из плана запроса.
Команду EXPLAIN можно использовать, чтобы показать разницу между планом с ограничением_исключением и планировать с этим.
У меня была похожая проблема, которую я смог решить путем приведения условий в WHERE. EG: (при условии, что столбец time_stamp имеет тип timestamptz)
WHERE time_stamp >= '2010-02-10'::timestamptz and time_stamp < '2010-02-11'::timestamptz
Также убедитесь, что условие CHECK в таблице определено таким же образом... ЭГ: CHECK (time_stamp < '2010-02-10'::timestamptz)