Здравствуйте! У нас в базе существует таблица, хранящая иерархию ( Parent_id -child_id). Тип id узлов иерархии- bigint. Тип выбран давно и его уже нельзя менять (во многих местах используется). Недавно понадобилось дополнительно произвести расчет данной иерархии ( с большим количеством данным). Кроме того, нужно было хранить цепочку (Materialized path), на основе которой получена связь parent_id-child_id. Пример :
parent_id-15926816
child_id - 15706021
Цепочка элементов
lpath- 15926816.15762121.15917825.16109332.15706021
В качестве типа поля lpath я стал использовать ltree.
CREATE TABLE test_gelt
(
parent_id bigint,
child_id bigint,
lpath ltree
)
WITH (
OIDS=FALSE
);
CREATE INDEX path_gist_idx
ON test_gelt
USING gist
(lpath);
CREATE INDEX path_idx
ON test_gelt
USING btree
(lpath);
В функциях часто нужно находить записи , где lpath содержит определенный участок:
select *
from public.test_gelt gelt
where
gelt.lpath ~ ('*.15697419.15891540.*')
План выполнения:
Bitmap Heap Scan on test_gelt gelt (cost=9677.33..334505.18 rows=100146 width=64)
Recheck Cond: (lpath ~ '*.15697419.15891540.*'::lquery)
-> Bitmap Index Scan on path_gist_idx (cost=0.00..9652.29 rows=100146 width=0)
Index Cond: (lpath ~ '*.15697419.15891540.*'::lquery)
Выяснилось, что если таблица public.test_gelt содержит 1 млн записей, то выборка достаточно быстрая, однако на реальных данных в 100 млн записей, даже при использовании индекса path_gist_idx работа запроса увеличивается до 2 минут. Подозреваю,что я плохо оценил скорость ltree на больших данных. Не хочется переделывать plpg-функции, ориентированные на работу с ltree.
Что можете посоветовать для увеличения выборки данных ltree по индексу?
Какие могут быть альтернативные типы данных для хранения и быстрого поиска в materialized path с учетом 100 миллионной таблицы?