PostgreSQL + разбиение таблиц: неэффективно max () и min () - PullRequest
0 голосов
/ 06 октября 2010

У меня есть огромная секционированная таблица, хранящаяся в таблице 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() запросов?

Спасибо

Адам

Ответы [ 3 ]

1 голос
/ 07 октября 2010

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

Вы всегда можете написать это как СОЮЗ из нескольких разделов, когда это просто необходимо сделать ...

1 голос
/ 06 октября 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;

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

0 голосов
/ 07 октября 2010

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

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

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

...