powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Создать индекс для рекурсивного запроса
2 сообщений из 2, страница 1 из 1
Создать индекс для рекурсивного запроса
    #40038814
polin11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть рекурсивный запрос в таблице Document для получение записей вниз по иерархии, идентификатор в таблице @Document.
Поле Hierarchy ссылка на идентификатор родительской записи.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
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



План выполнения запроса:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
"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?
...
Рейтинг: 0 / 0
Создать индекс для рекурсивного запроса
    #40038816
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11,

1)rows=766 - просто слишком мало чтобы index scan включался...
seq scan вероятнее всего будет быстрее это первое

2)второе - база ожидает что
" -> 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")"
по "Document"."Hierarchy" = hier_down_1."@Document" вернется 389 строк а реально возвращается одна строка...

у вас там статистика распределения данных очень странная судя по всему очень и очень неровная
и в такой ситуации seq scan/hash join будет быстрее (исходя из того что база себе думает).


сделайте analyze "Document";
и покажите что у вас показывает
select null_frac, n_distinct, most_common_vals,most_common_freqs from pg_stats where tablename='Document' and attname='Hierarchy';
?

PS: у вас постановка вопроса не верная и вопрос не про подходящий индекс (подходящий тут по Document.Hierarchy where Hierarchy is not null скорее всего, но использоваться он не будет потому что выше).

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Создать индекс для рекурсивного запроса
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]