2016-08-25 1 views
0

СитуацияТабличка с модулем, как индексировать? PostgreSQL

У меня есть база данных в PostgreSQL 9.5, используемые для хранения местоположения объекта по времени.

Я главная таблица с именем "позиция" с колонками (только соответствующие):

  • position_id
  • position_timestamp
  • object_id

Он разделен на 100 дочерних таблиц на object_id с условием:

CREATE TABLE position_object_id_00 
(CHECK object_id%100 = 0) 
INHERITS (position); 

И так далее для остальных детей. Я разделял модульное отношение для равномерного распределения объектов. Каждый ребенок индексируется на position_id и object_id (два разных индекса).

Выпуск

Когда я смотрю на объект по его ID, Postgres запускает сканирование индекса на каждом ребенок таблице:

EXPLAIN ANALYZE 
SELECT * 
FROM position 
WHERE object_id = 3 

"Append (cost=0.43..35925.81 rows=51119 width=97) (actual time=0.109..46.362 rows=52418 loops=1)" 
" -> Index Scan using position_object_id_position_timestamp_idx on position (cost=0.43..34742.00 rows=24811 width=97) (actual time=0.108..15.367 rows=26209 loops=1)" 
"  Index Cond: (object_id = 3)" 
" -> Index Scan using position_object_id_00_object_id_idx on position_object_id_00 (cost=0.29..4.30 rows=1 width=97) (actual time=0.102..0.102 rows=0 loops=1)" 
"  Index Cond: (object_id = 3)" 
" -> Index Scan using position_object_id_01_object_id_idx on position_object_id_01 (cost=0.29..4.30 rows=1 width=97) (actual time=0.065..0.065 rows=0 loops=1)" 
"  Index Cond: (object_id = 3)" 
" -> Index Scan using position_object_id_02_object_id_idx on position_object_id_02 (cost=0.29..4.30 rows=1 width=97) (actual time=0.069..0.069 rows=0 loops=1)" 
"  Index Cond: (object_id = 3)" 
" -> Seq Scan on position_object_id_03 (cost=0.00..757.61 rows=26209 width=97) (actual time=0.030..5.337 rows=26209 loops=1)" 
"  Filter: (object_id = 3)" 
" -> Index Scan using position_object_id_04_object_id_idx on position_object_id_04 (cost=0.29..4.30 rows=1 width=97) (actual time=0.067..0.067 rows=0 loops=1)" 
"  Index Cond: (object_id = 3)" 

[...] 

За исключением того факта, что есть данные в моей главной таблице (первая строка) (см. раздел об этом Before and After trigger on the same event? Fill a child table PostgreSQL), Postgres не «распознает» условие проверки для раздела и ищет идентификатор в каждой дочерней таблице, тогда как в таблице position_object_id_03 имеется только соответствующий идентификатор.

Есть ли особый способ индексирования, чтобы он непосредственно знал, на какую таблицу посмотреть?

Благодарим за помощь!

ответ

1

Postgres не может автоматически применить знания о том, что object_id = 3 к ограничению проверки, решите, что 3 % 100 = 3 и выберите соответствующий раздел. Единственный способ намекнуть Postgres, какой раздел, чтобы выбрать это явно использовать выражение из проверочного ограничения в запросе, как:

SELECT * FROM position WHERE object_id = 3 AND object_id % 100 = 3; 

Btw, мы разрабатываем расширение с открытым исходным кодом для разбиения (pg_pathman), который построил - в поддержку хэш-разбиения, и он автоматически понимает, что object_id = 3 соответствует определенному разделу. Пожалуйста, проверьте это.

+0

Благодарим вас за ответ. Я также хочу иметь поле «object_partition», которое будет хранить 'object_id% 100', так что мы можем запросить на' object_id = sth AND object_partition = sth% 100'. Это очень похоже :) – Miwauke

Смежные вопросы