Разделение таблиц PostgreSQL+: неэффективные max() и min()

У меня есть огромная секционированная таблица, хранящаяся в таблице PostgreSQL. Каждая дочерняя таблица имеет индекс и проверочное ограничение для своего идентификатора, например. (неуместные детали удалены для ясности):

Master table: points
    Column     |            Type             |       Modifiers        
---------------+-----------------------------+------------------------
 id            | bigint                      |
 creation_time | timestamp without time zone | 
 the_geom      | geometry                    | 


Sub-table points_01
    Column     |            Type             |        Modifiers        
---------------+-----------------------------+-------------------------
     id            | bigint                      | 
 creation_time | timestamp without time zone | 
 the_geom      | geometry                    | 

Indexes:
    "points_01_pkey" PRIMARY KEY, btree (id)
    "points_01_creation_time_idx" btree (creation_time)
    "points_01_the_geom_idx" gist (the_geom) CLUSTER
Check constraints:
    "enforce_srid_the_geom" CHECK (srid(the_geom) = 4326)
    "id_gps_points_2010_08_22__14_47_04_check" 
               CHECK (id >= 1000000::bigint AND id <= 2000000::bigint)

Сейчас,

SELECT max(id) FROM points_01

мгновенно, но:

SELECT max(id) FROM points

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

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

Есть ли хороший хак, который заставит планировщик запросов использовать проверочные ограничения и индексы подтаблиц для запросов max() и min()?

Спасибо,

Адам


person Adam Matan    schedule 06.10.2010    source источник
comment
Можете ли вы показать свой план выполнения?   -  person Pablo Santa Cruz    schedule 06.10.2010


Ответы (3)


Краткий ответ: нет. На данный момент нет способа заставить планировщик Postgres понять, что некоторые агрегатные функции могут сначала проверять ограничения для дочерних разделов. Это довольно легко доказать для конкретного случая минимума и максимума, но для агрегатов в целом это сложный случай.

Вы всегда можете написать это как ОБЪЕДИНЕНИЕ нескольких разделов, когда это просто нужно сделать...

person rfusca    schedule 06.10.2010

Я не знаю, сработает ли это, но вы можете попробовать это:

Для этого сеанса вы можете отключить все стратегии доступа, кроме индексированных:

db=> set enable_seqscan = off;
db=> set enable_tidscan = off;
db=> -- your query goes here

Таким образом, будут включены только bitmapscan и indexscan. У PostgreSQL не будет другого выбора, кроме как использовать индексы для доступа к данным в таблице.

После выполнения запроса не забудьте повторно включить seqscan и tidscan, выполнив следующие действия:

db=> set enable_seqscan = on;
db=> set enable_tidscan = on;

В противном случае эти стратегии доступа будут отключены для сеанса с этого момента.

person Pablo Santa Cruz    schedule 06.10.2010
comment
Являются ли эти настройки специфичными для сеанса или глобальными? - person Adam Matan; 06.10.2010
comment
Вы можете сделать их глобальными, изменив postgresql.conf. Но я настоятельно не рекомендую вам это делать. Если вы используете set, они будут зависеть от сеанса. Как я указал в ответе, отключите seqscan и tidscan ТОЛЬКО ДЛЯ ЭТОГО ЗАПРОСА и немедленно включите их снова. - person Pablo Santa Cruz; 06.10.2010

Я мало что знаю о postgres, но вы можете попробовать этот запрос (синтаксис моего запроса может быть неправильным из-за отсутствия опыта работы с запросами postgres):

SELECT id FROM points a WHERE id > ALL (SELECT id FROM x WHERE x.id != a.id)

Мне интересно, работает ли это.

person ITroubs    schedule 07.10.2010