Использую PostgreSQL, есть иерархическая таблица Document, есть простой рекурсивный запрос, получаем записи вниз по иерархии, поле иерархии Hier код SQL | | 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 запрос выполняется быстро код SQL | 1: | 2: | 3: | 4: | 5: | 6: | 7: | 8: | 9: | 10: | 11: | 12: | 13: | 14: | 15: | 16: |
| "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 и запрос выполняется очень долго и много ресурсов использует код SQL | 1: | 2: | 3: | 4: | 5: | 6: | 7: | 8: | 9: | 10: | 11: | 12: | 13: | 14: | 15: | 16: | 17: | 18: | 19: |
| "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?
|