LINUX.ORG.RU

Создать индекс для рекурсивного запроса

 ,


0

1

Иcпользую PostreSQL, есть рекурсивный запрос в таблице Document для получение записей вниз по иерархии, идентификатор в таблице @Document. Поле Hierarchy ссылка на идентификатор родительской записи.

EXPLAIN (ANALYZE,BUFFERS)
        WITH  RECURSIVE 
                hier_down AS(
                    SELECT
                       h."@Document",
                       h."Hierarchy",
                       h."Hint"
					   FROM "Document" h
                       WHERE
                          "@Document" = 13
                    UNION all
                    SELECT
                        "Document" ."@Document",
                         "Document" ."Hierarchy",
                         "Document"."Hint"
                    FROM hier_down, "Document" 
                    WHERE   "Document"."Hierarchy" =  hier_down."@Document"
                )
SELECT *
FROM hier_down

План выполнения запроса:

"CTE Scan on hier_down  (cost=783.59..861.41 rows=3891 width=44) (actual time=0.008..0.748 rows=5 loops=1)"
"  Buffers: shared hit=281"
"  CTE hier_down"
"    ->  Recursive Union  (cost=0.28..783.59 rows=3891 width=76) (actual time=0.007..0.745 rows=5 loops=1)"
"          Buffers: shared hit=281"
"          ->  Index Scan using "pDocument" on "Document" h  (cost=0.28..8.29 rows=1 width=76) (actual time=0.006..0.006 rows=1 loops=1)"
"                Index Cond: ("@Document" = 13110)"
"                Buffers: shared hit=3"
"          ->  Hash Join  (cost=0.33..69.75 rows=389 width=76) (actual time=0.044..0.143 rows=1 loops=5)"
"                Hash Cond: ("Document"."Hierarchy" = hier_down_1."@Document")"
"                Buffers: shared hit=278"
"                ->  Seq Scan on "Document"  (cost=0.00..62.66 rows=766 width=76) (actual time=0.003..0.061 rows=766 loops=5)"
"                      Buffers: shared hit=275"
"                ->  Hash  (cost=0.20..0.20 rows=10 width=4) (actual time=0.002..0.002 rows=1 loops=5)"
"                      Buckets: 1024  Batches: 1  Memory Usage: 9kB"
"                      ->  WorkTable Scan on hier_down hier_down_1  (cost=0.00..0.20 rows=10 width=4) (actual time=0.000..0.000 rows=1 loops=5)"
"Planning time: 0.336 ms"
"Execution time: 0.786 ms"

Хочется избавиться от seq scan Есть индекс по полю Hierarchy - он не используется Есть составной индекс (Hierarchy, @Document ) - он не используется

сделал индекс

CREATE INDEX "Hier"
ON "Document" USING btree
("Hierarchy" NULLS LAST, "@Document" NULLS LAST, "Hint" NULLS LAST);
он используется, но перестает использоваться когда добавляется новое поле в SELECT, приходится добавлять новое поле в индекс.

Как бы создать индекс, на который не влиял бы набор полей в SELECT?

«Хочется избавиться от seq scan» - почему хочется? индекс ради индекса? раз база не использует индекс значит она считает, что он не будет самым эффективным способом получения данных. такие вещи надо смотреть на реальных данных, а не на rows=766. так же надо учитывать, что индекс подходит далеко не для всех данных, analyze в руки.

ну и общее - деревянные запросы, очень плохо ложатся на индексы. Посему, если это критичные/центральные вещи, не надо их использовать, есть куча способов сделать по человечески по база данновски.

vtVitus ★★★★★
()
Последнее исправление: vtVitus (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.