请帮助优化请求。我不明白为什么使用 ORDER BY 实际时间会增加几倍至 150 毫秒,而没有 ORDER BY 15-5 毫秒。也许需要某种索引,但我不知道是哪一个
explain analyze
with recursive src as(
select
d.station_id1 border_form,
d.station_id2 border_to,
d.country_key_station_id1 code1,
d.country_key_station_id2 code2,
'/' || d.country_key_station_id1 || '/' || d.country_key_station_id2 || '/' as route,
'' as route_distance,
d.distance
from
test_distance.distances_border d
where
d.country_key_station_id1 = 20
union all
select
s.border_form,
d1.station_id2 as border_to,
s.code1,
d1.country_key_station_id2 as code2,
s.route || d1.country_key_station_id2 || '/' as route,
s.route_distance || dc.distance || '+' as route_distance,
s.distance + dc.distance as distance
from
test_distance.distances_border d1
join src s on d1.country_key_station_id1 = s.code2
and not s.route like '%/' || d1.country_key_station_id2 || '/%'
join test_distance.distances_border_in_country dc on s.border_to =
dc.station_id1
and d1.station_id1 = dc.station_id2
)
select
border_form,
border_to,
code1,
code2,
dist_start,
dist_transit,
dist_end,
route,
distance + dist_start + dist_end as distance
from (
select
border_form,
border_to,
code1,
code2,
test_distance.get_distance('910000' , border_form, code1) as dist_start,
route_distance as dist_transit,
test_distance.get_distance(border_to , '720903', code2) as dist_end,
route,
distance
from src s
where code2 = 29
order by distance
) r
如果按距离排序完全放在最后,那么实际时间会变得更长,从 180 毫秒开始,如果有人给我一个想法,我将不胜感激
查询计划
Subquery Scan on r (cost=830.05..830.07 rows=1 width=160) (actual time=73.354..73.357 rows=22 loops=1)
CTE src
-> Recursive Union (cost=0.00..825.38 rows=185 width=125) (actual time=0.030..7.470 rows=1046 loops=1)
-> Seq Scan on distances_border d (cost=0.00..4.70 rows=35 width=26) (actual time=0.024..0.135 rows=35 loops=1)
Filter: (country_key_station_id1 = 20)
Rows Removed by Filter: 125
-> Hash Join (cost=32.86..81.70 rows=15 width=125) (actual time=0.948..1.189 rows=169 loops=6)
Hash Cond: (((dc.station_id1)::text = (s_1.border_to)::text) AND ((dc.station_id2)::text = (d1.station_id1)::text))
-> Seq Scan on distances_border_in_country dc (cost=0.00..27.60 rows=1660 width=18) (actual time=0.002..0.065 rows=1660 loops=5)
-> Hash (cost=28.68..28.68 rows=279 width=166) (actual time=0.882..0.882 rows=508 loops=6)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
-> Hash Join (cost=11.38..28.68 rows=279 width=166) (actual time=0.273..0.749 rows=508 loops=6)
Hash Cond: (d1.country_key_station_id1 = s_1.code2)
Join Filter: (s_1.route !~~ (('%/'::text || (d1.country_key_station_id2)::text) || '/%'::text))
Rows Removed by Join Filter: 1475
-> Seq Scan on distances_border d1 (cost=0.00..3.60 rows=160 width=22) (actual time=0.002..0.010 rows=160 loops=6)
-> Hash (cost=7.00..7.00 rows=350 width=152) (actual time=0.046..0.046 rows=174 loops=6)
Buckets: 1024 Batches: 1 Memory Usage: 23kB
-> WorkTable Scan on src s_1 (cost=0.00..7.00 rows=350 width=152) (actual time=0.001..0.017 rows=174 loops=6)
-> Sort (cost=4.67..4.68 rows=1 width=152) (actual time=73.351..73.352 rows=22 loops=1)
Sort Key: s.distance
Sort Method: quicksort Memory: 28kB
-> CTE Scan on src s (cost=0.00..4.66 rows=1 width=152) (actual time=7.986..73.318 rows=22 loops=1)
Filter: (code2 = 29)
Rows Removed by Filter: 1024
Planning time: 1.990 ms
Execution time: 73.654 ms
我看到好像一直在排序,但是我不知道如何理解写的内容:(
我发现在内部函数中我在表 st1、st2 上进行了搜索,我在上面放了一个索引,现在执行需要 3ms。