如何解决是否有可能为包含使用订单子句的窗口函数的查询制定完整的并行计划例如,带有order by的累加总和?
因此,我有一个查询,该查询首先将一个大表(5Mio记录)与其他几个表连接在一起。通过首先指定以下内容,查询的这一部分完全平行:
set max_parallel_workers_per_gather = 12;
set parallel_setup_cost = 0;--1000
set parallel_tuple_cost = 0;
set max_parallel_maintenance_workers = 4;
set min_parallel_table_scan_size to '1kB';
这是查询:
explain analyze
with subca as
(
(with z as (
select 12 as se_id,405 as pe_id,dt.zo_id,dt.co_id,sh.sh_id,n.ct_id,cast(coalesce(com.value_num,1) * rere.value_num * n.csv * cast(case when shop_concept =2 and n.ct_id = 1 then (0.01) * (greatest(1+ (pn_cvp_public_transport/1400000)+ ln(least(greatest(activity_map_fte,4000),150000)/60000)/7,0.1)) * (1/exp(dt*ddp)) when shop_concept =1 and n.ct_id = 1 then (0.01) * (greatest(1
+(total_openinghours-35)*0.018
+ (atm-2)*0.05
+ 0.15*(last_significant_works-2)
- (open_saturday-1)*0.05
+ ln(least(greatest(activity_map_fte,25000),150000)/60000)/7
+ case centrally_located_avg when 1 then -0.1 when 3 then 0.06 else 0.0 end
+(greatest(nps,30)-60)/600
+case when parking = 1 then 0.03 else 0 end
+ case passage_foot when 1 then -0.05 when 4 then 0.03 when 5 then 0.06 else 0.0 end
+case when nr_fte < 2.5 then -0.12 else 0.0 end
+case when nr_fte >= 4.5 then 0.15 else 0.0 end
+case when pn_cvp_services = 0 then -0.05 when pn_cvp_services > 15 then 0.05 else 0 end
+ pn_cvp_non_fashion/40000,0.01)) * (1/((greatest(least(rev_wealthy,1.8),0.6)^1.5)*exp((dt*ddp+0.35)+0.1))) end as double precision) as float) as attraction,0.1)) * (0.01/exp(dt*nddp)) when shop_concept =1 and n.ct_id = 1 then (0.01) * (greatest(1
+(total_openinghours-35)*0.018
+ (atm-2)*0.05
+ 0.15*(last_significant_works-2)
- (open_saturday-1)*0.05
+ ln(least(greatest(activity_map_fte,0.01)) * ((0.03+((urbanization_v2-2200)/1000000)-if(urbanization_v2<1000,urbanization_v2/50000,0)
)
/((greatest(least(rev_wealthy,1.5),0.7)^1.5)*exp(dt*nddp))) end as double precision) as float) as nd_attraction,n.fc
from (select pe_id,zo_id,co_id,value_num as dt
from rtpezocoav x --use view??
where pe_id = 405 and ad_id = 4
) dt
join calc_nodes n on n.co_id = dt.co_id and n.pe_id = 405 and n.se_id = 12
join calc_zones z on dt.zo_id = z.zo_id and z.pe_id = 405 and z.se_id = 12
--!!
left join calc_shopconcepts sh on sh.pe_id = 405 and sh.se_id = 12 and sh.sh_id = n.shop_concept and sh.ct_id = n.ct_id
left join rtsepezobrav com on com.se_id = 12 and com.pe_id = 405 and com.zo_id = z.zo_id and com.br_id = n.br_id and com.ad_id = 308
join rtseperereav rere on rere.se_id = 12 and rere.pe_id = 405 and rere.re_id = z.re_id and rere.re2_id = n.re_id and rere.ad_id = 306
)
select se_id,pe_id,sh_id,ct_id,attraction::float,nd_attraction::float,fc from z)
),alloc as
(
select
ca.co_id as nodeid,ca.zo_id as zoneid,ic.br_id as ownerid,ic.br2_id as to_owner,(ca.attraction*ca.fc) as attraction,(ca.nd_attraction*ca.fc) as nd_attraction,ca.sh_id as shopconcept,ca.ct_id,ic.value_num as value,least(sum(ic.value_num) over w,30) as r -- Calculate rank within zone for a given owner (avoid overflow)
-- Get attractions a(z,n)
from subca ca --modify for simulations
join rtco co on co.lo_id = ca.co_id
join rvsepebrbrav ic on ic.se_id = 12 and ic.pe_id = 405 and co.br_id = ic.br_id and ic.ad_id = 307 --modify se/pe
window
w as (partition by ca.zo_id,ic.br2_id order by ca.attraction desc)
)
select sum(r) from alloc;
如果我执行select count(1) from alloc
或select sum(attraction) from alloc
,查询将完全并行运行。当我包括上述窗口功能时,问题就开始了。然后该计划显示了并行进行的连接,接着是一个收集步骤,然后是一个大型排序,这使得查询非常慢:
Aggregate (cost=981588.52..981588.53 rows=1 width=8) (actual time=5844.082..5844.083 rows=1 loops=1)
-> WindowAgg (cost=859448.88..937967.22 rows=3489704 width=64) (actual time=3112.764..5653.421 rows=5019003 loops=1)
-> Sort (cost=859448.88..868173.14 rows=3489704 width=20) (actual time=3112.751..3773.671 rows=5019003 loops=1)
Sort Key: x.zo_id,((((COALESCE(com.value_num,'1'::double precision) * rere.value_num) * n.csv) * CASE WHEN ((n.shop_concept = '2'::double precision) AND (n.ct_id = 1)) THEN (('0.01'::double precision * G
REATEST((('1'::double precision + (n.pn_cvp_public_transport / '1400000'::double precision)) + (ln((LEAST(GREATEST(n.activity_map_fte,'4000'::double precision),'150000'::double precision) / '60000'::double precision))
/ '7'::double precision)),'0.1'::double precision)) * ('1'::double precision / exp((x.value_num * sh.ddp)))) WHEN ((n.shop_concept = '1'::double precision) AND (n.ct_id = 1)) THEN (('0.01'::double precision * GREATEST((
(((((((((((('1'::double precision + ((n.total_openinghours - '35'::double precision) * '0.018'::double precision)) + ((n.atm - '2'::double precision) * '0.05'::double precision)) + ('0.15'::double precision * (n.last_sig
nificant_works - '2'::double precision))) - ((n.open_saturday - '1'::double precision) * '0.05'::double precision)) + (ln((LEAST(GREATEST(n.activity_map_fte,'25000'::double precision),'150000'::double precision) / '600
00'::double precision)) / '7'::double precision)) + (CASE n.centrally_located_avg WHEN '1'::double precision THEN '-0.1'::numeric WHEN '3'::double precision THEN 0.06 ELSE 0.0 END)::double precision) + ((GREATEST(n.nps,'30'::double precision) - '60'::double precision) / '600'::double precision)) + (CASE WHEN (n.parking = '1'::double precision) THEN 0.03 ELSE '0'::numeric END)::double precision) + (CASE n.passage_foot WHEN '1'::double p
recision THEN '-0.05'::numeric WHEN '4'::double precision THEN 0.03 WHEN '5'::double precision THEN 0.06 ELSE 0.0 END)::double precision) + (CASE WHEN (n.nr_fte < '2.5'::double precision) THEN '-0.12'::numeric ELSE 0.0 E
ND)::double precision) + (CASE WHEN (n.nr_fte >= '4.5'::double precision) THEN 0.15 ELSE 0.0 END)::double precision) + (CASE WHEN (n.pn_cvp_services = '0'::double precision) THEN '-0.05'::numeric WHEN (n.pn_cvp_services
> '15'::double precision) THEN 0.05 ELSE '0'::numeric END)::double precision) + (n.pn_cvp_non_fashion / '40000'::double precision)),'0.01'::double precision)) * ('1'::double precision / ((GREATEST(LEAST(z.rev_wealthy,'
1.8'::double precision),'0.6'::double precision) ^ '1.5'::double precision) * exp((((x.value_num * sh.ddp) + '0.35'::double precision) + '0.1'::double precision))))) ELSE NULL::double precision END)) DESC
Sort Method: quicksort Memory: 588718kB
-> Gather (cost=5567.42..480211.00 rows=3489704 width=20) (actual time=37.774..913.148 rows=5019003 loops=1)
Workers Planned: 8
Workers Launched: 7
-> Parallel Hash Join (cost=5567.42..480211.00 rows=436213 width=20) (actual time=6.002..985.253 rows=627375 loops=8)
Hash Cond: (co.br_id = "*SELECT* 2".br_id)
-> Parallel Hash Join (cost=5503.34..476904.02 rows=436213 width=16) (actual time=5.788..902.602 rows=627375 loops=8)
Hash Cond: (x.co_id = co.lo_id)
-> Parallel Hash Join (cost=5352.49..432692.78 rows=436213 width=48) (actual time=5.066..816.680 rows=627375 loops=8)
Hash Cond: ((z.re_id = rere.re_id) AND (n.re_id = rere.re2_id))
-> Hash Left Join (cost=5339.56..343643.93 rows=436213 width=172) (actual time=4.980..408.478 rows=627375 loops=8)
Hash Cond: ((z.zo_id = com.zo_id) AND (n.br_id = com.br_id))
-> Parallel Hash Join (cost=5331.37..341345.62 rows=436213 width=172) (actual time=4.967..313.702 rows=627375 loops=8)
Hash Cond: (x.zo_id = z.zo_id)
-> nested Loop (cost=14.15..331131.09 rows=435194 width=156) (actual time=0.277..169.299 rows=627375 loops=8)
-> Parallel Hash Left Join (cost=13.58..2718.31 rows=608 width=144) (actual time=0.239..1.337 rows=616 loops=8)
Hash Cond: ((n.shop_concept = (sh.sh_id)::double precision) AND (n.ct_id = sh.ct_id))
-> Parallel Seq Scan on calc_nodes n (cost=0.00..2699.38 rows=608 width=136) (actual time=0.113..0.857 rows=616 loops=8)
Filter: ((pe_id = 405) AND (se_id = 12))
Rows Removed by Filter: 5543
-> Parallel Hash (cost=13.57..13.57 rows=1 width=16) (actual time=0.024..0.024 rows=0 loops=8)
Buckets: 1024 Batches: 1 Memory Usage: 40kB
-> Parallel Bitmap Heap Scan on calc_shopconcepts sh (cost=4.30..13.57 rows=1 width=16) (actual time=0.020..0.021 rows=1 loops=4)
Recheck Cond: ((pe_id = 405) AND (se_id = 12))
Heap Blocks: exact=2
-> Bitmap Index Scan on idx_calc_shopconcepts_sepebr (cost=0.00..4.30 rows=3 width=0) (actual time=0.024..0.024 rows=3 loops=1)
Index Cond: ((pe_id = 405) AND (se_id = 12))
-> Index Scan using rtpezocoav_ad_id_pe_id_co_id_index on rtpezocoav x (cost=0.56..533.00 rows=715 width=16) (actual time=0.009..0.142 rows=1019 loops=4924)
Index Cond: ((ad_id = 4) AND (pe_id = 405) AND (co_id = n.co_id))
-> Parallel Hash (cost=5283.15..5283.15 rows=2726 width=16) (actual time=4.616..4.616 rows=2721 loops=8)
Buckets: 32768 Batches: 1 Memory Usage: 1280kB
-> Parallel Seq Scan on calc_zones z (cost=0.00..5283.15 rows=2726 width=16) (actual time=2.660..5.298 rows=3628 loops=6)
Filter: ((pe_id = 405) AND (se_id = 12))
Rows Removed by Filter: 32652
-> Hash (cost=8.17..8.17 rows=1 width=16) (actual time=0.005..0.005 rows=0 loops=8)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
-> Index Scan using rtsepezobrav_unique on rtsepezobrav com (cost=0.15..8.17 rows=1 width=16) (actual time=0.005..0.005 rows=0 loops=8)
Index Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 308))
-> Parallel Hash (cost=12.87..12.87 rows=4 width=16) (actual time=0.004..0.004 rows=1 loops=8)
Buckets: 1024 Batches: 1 Memory Usage: 40kB
-> Parallel Bitmap Heap Scan on rtseperereav rere (cost=4.39..12.87 rows=4 width=16) (actual time=0.018..0.020 rows=9 loops=1)
Recheck Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 306))
Heap Blocks: exact=1
-> Bitmap Index Scan on rtseperereav_unique (cost=0.00..4.39 rows=9 width=0) (actual time=0.011..0.011 rows=9 loops=1)
Index Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 306))
-> Parallel Hash (cost=108.71..108.71 rows=3371 width=8) (actual time=0.696..0.696 rows=1683 loops=8)
Buckets: 16384 Batches: 1 Memory Usage: 672kB
-> Parallel Seq Scan on rtco co (cost=0.00..108.71 rows=3371 width=8) (actual time=0.008..2.058 rows=13464 loops=1)
-> Parallel Hash (cost=63.99..63.99 rows=7 width=12) (actual time=0.038..0.038 rows=2 loops=8)
Buckets: 1024 Batches: 1 Memory Usage: 40kB
-> Parallel Append (cost=4.51..63.99 rows=7 width=12) (actual time=0.062..0.115 rows=17 loops=1)
-> Subquery Scan on "*SELECT* 2" (cost=38.55..38.79 rows=1 width=12) (actual time=0.042..0.042 rows=0 loops=1)
-> Merge Anti Join (cost=38.55..38.78 rows=1 width=64) (actual time=0.041..0.041 rows=0 loops=1)
Merge Cond: ((av.br_id = av_1.br_id) AND (av.br2_id = av_1.br2_id))
Join Filter: ((av_1.pe_id = rtpe.id) AND (av_1.se_id = av.se_id) AND (av_1.ad_id = av.ad_id))
-> Sort (cost=33.49..33.52 rows=10 width=28) (actual time=0.039..0.039 rows=0 loops=1)
Sort Key: av.br_id,av.br2_id
Sort Method: quicksort Memory: 25kB
-> nested Loop (cost=8.76..33.33 rows=10 width=28) (actual time=0.034..0.034 rows=0 loops=1)
-> Parallel Bitmap Heap Scan on rtpe (cost=4.28..8.29 rows=1 width=8) (actual time=0.022..0.023 rows=1 loops=1)
Recheck Cond: (id = 405)
Heap Blocks: exact=1
-> Bitmap Index Scan on rtpe_id_baseline_id_idx (cost=0.00..4.28 rows=1 width=0) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (id = 405)
-> Bitmap Heap Scan on rtsepebrbrav av (cost=4.48..24.88 rows=16 width=28) (actual time=0.004..0.004 rows=0 loops=1)
Recheck Cond: ((se_id = 12) AND (pe_id = rtpe.baseline_id) AND (ad_id = 307))
-> Bitmap Index Scan on rtsepebrbrav_unique (cost=0.00..4.48 rows=16 width=0) (actual time=0.001..0.001 rows=0 loops=1)
Index Cond: ((se_id = 12) AND (pe_id = rtpe.baseline_id) AND (ad_id = 307))
-> Sort (cost=5.06..5.11 rows=18 width=20) (never executed)
Sort Key: av_1.br_id,av_1.br2_id
-> Index Only Scan using rtsepebrbrav_unique on rtsepebrbrav av_1 (cost=0.28..4.68 rows=18 width=20) (never executed)
Index Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 307))
Heap Fetches: 0
-> Parallel Bitmap Heap Scan on rtsepebrbrav (cost=4.51..25.17 rows=6 width=12) (actual time=0.061..0.069 rows=17 loops=1)
Recheck Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 307))
Heap Blocks: exact=2
-> Bitmap Index Scan on rtsepebrbrav_unique (cost=0.00..4.50 rows=18 width=0) (actual time=0.036..0.036 rows=17 loops=1)
Index Cond: ((se_id = 12) AND (pe_id = 405) AND (ad_id = 307))
Planning Time: 8.603 ms
Execution Time: 5888.474 ms
我猜想计划者需要收集,因为它需要评估所有行,但是如果我能以某种方式告诉/指导计划者每个zo-id值仅在一个工作人员的范围内,排序可以并行进行。这有可能吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。