Использую PostgreSQL, есть иерархическая таблица Document, есть простой рекурсивный запрос, получаем записи вниз по иерархии, поле иерархии Hier
WITH RECURSIVE DOWN AS(
SELECT s.*
FROM "Document" s
WHERE "Hier" = 1123
UNION
SELECT s1.*
FROM DOWN
INNER JOIN "Document" s1 ON s1."Hier"= DOWN."@Document"
)
SELECT *
FROM DOWN
На одной БД планировщик использует Nested Loop запрос выполняется быстро
"CTE Scan on down (cost=229320.82..231171.20 rows=92519 width=253) (actual time=0.207..2.038 rows=17 loops=1)"
" Buffers: shared hit=62 read=3"
" CTE down"
" -> Recursive Union (cost=0.43..229320.82 rows=92519 width=272) (actual time=0.202..2.005 rows=17 loops=1)"
" Buffers: shared hit=62 read=3"
" -> Index Scan using "iDocument-Hier" on "Document" s (cost=0.43..27.52 rows=9 width=272) (actual time=0.194..0.203 rows=4 loops=1)"
" Index Cond: ("Hier" = 4634473)"
" Buffers: shared hit=7 read=1"
" -> Nested Loop (cost=0.43..22744.29 rows=9251 width=272) (actual time=0.831..0.870 rows=6 loops=2)"
" Buffers: shared hit=55 read=2"
" -> WorkTable Scan on down down_1 (cost=0.00..1.80 rows=90 width=8) (actual time=0.001..0.008 rows=8 loops=2)"
" -> Index Scan using "iDocument-Hier" on "Document" s1 (cost=0.43..251.66 rows=103 width=272) (actual time=0.096..0.098 rows=1 loops=17)"
" Index Cond: ("Hier" = down_1."@Document")"
" Buffers: shared hit=55 read=2"
"Planning time: 1.200 ms"
"Execution time: 3.596 ms"
На другой БД с примерно теми же данными используется Merge Join и запрос выполняется очень долго и много ресурсов использует
"CTE Scan on down (cost=14385858.75..16871148.97 rows=124264511 width=253) (actual time=7.388..54128.588 rows=17 loops=1)"
" Buffers: shared hit=562520 read=190529"
" CTE down"
" -> Recursive Union (cost=0.56..14385858.75 rows=124264511 width=277) (actual time=7.383..54128.547 rows=17 loops=1)"
" Buffers: shared hit=562520 read=190529"
" -> Index Scan using "iDocument-Hier" on "Document" s (cost=0.56..1610.97 rows=581 width=277) (actual time=7.373..9.128 rows=4 loops=1)"
" Index Cond: ("Hier" = 939969)"
" Buffers: shared read=7"
" -> Merge Join (cost=480.01..1189895.76 rows=12426393 width=277) (actual time=27057.258..27059.673 rows=6 loops=2)"
" Merge Cond: (s1."Hier" = down_1."@Document")"
" Buffers: shared hit=562520 read=190522"
" -> Index Scan using "iDocument-Hier" on "Document" s1 (cost=0.56..986143.92 rows=6750595 width=277) (actual time=0.706..26652.712 rows=2957380 loops=2)"
" Buffers: shared hit=562520 read=190522"
" -> Sort (cost=479.45..493.98 rows=5810 width=8) (actual time=0.034..0.040 rows=11 loops=2)"
" Sort Key: down_1."@Document""
" Sort Method: quicksort Memory: 25kB"
" -> WorkTable Scan on down down_1 (cost=0.00..116.20 rows=5810 width=8) (actual time=0.003..0.004 rows=8 loops=2)"
"Planning time: 1.677 ms"
"Execution time: 54145.287 ms"
В обеих базах есть индекс по полю Hier, пробовал выполнить vacuum analyze, reindex, обновить статистику для планировщика - ничего не помогает.
Как решить проблему на второй базе, заставить планировщик использовался Nested Loop?