Запрос SQL, как показано ниже, вызывает заполнение одного узла диска кластера Redshift
insert
into
report.agg_info
( pd ,idate ,idate_str ,app_class ,app_superset ,aid ,pf ,is ,camp ,ua_camp_id ,country ,is_predict ,cohort_size ,new_users ,retained ,acc_re ,day_iap_rev ,iap_rev ,day_rev ,rev )
select
p.pd ,
p.idate ,
p.idate_str ,
p.app_class ,
p.app_superset ,
p.aid ,
p.pf ,
p.is ,
p.camp ,
p.ua_camp_id ,
p.country ,
1 as is_predict ,
p.cohort_size ,
p.new_users ,
p.retained ,
ar.acc_re ,
p.day_iap_rev ,
ar.iap_rev ,
p.day_rev ,
ar.rev
from
tmp_predict p
join
tmp_accumulate ar
on p.pd = ar.pd
and p.idate = ar.idate
and p.aid = ar.aid
and p.pf = ar.pf
and p.is = ar.is
and p.camp = ar.camp
and p.ua_camp_id = ar.ua_camp_id
and p.country = ar.country
И план запроса:
XN Hash Join DS_DIST_BOTH (cost=11863664.64..218084556052252.12 rows=23020733790769 width=218)
-> XN Seq Scan on tmp_predict p (cost=0.00..3954554.88 rows=395455488 width=188)
-> XN Hash (cost=3954554.88..3954554.88 rows=395455488 width=165)
-> XN Seq Scan on tmp_accumulate ar (cost=0.00..3954554.88 rows=395455488 width=165)
Из приведенного выше изображения мы знаем, что node-39
содержит больше данных, чем другие узлы. Потому что данные искажены на join
.
Чтобы решить эту проблему, мы стараемся использовать update
вместо join
update
report.agg_info
set
acc_re = ar.acc_re,
iap_rev = ar.iap_rev,
rev = ar.rev
from
tmp_accumulate ar
where
report.agg_info.pd = ar.pd
and report.agg_info.idate = ar.idate
and report.agg_info.aid = ar.aid
and report.agg_info.pf = ar.pf
and report.agg_info.is = ar.is
and report.agg_info.camp = ar.camp
and report.agg_info.ua_camp_id = ar.ua_camp_id
and report.agg_info.country = ar.country
План запроса
XN Hash Join DS_BCAST_INNER (cost=11863664.64..711819961371132.00 rows=91602 width=254)
-> XN Seq Scan on agg_info (cost=0.00..2.70 rows=270 width=224)
-> XN Hash (cost=3954554.88..3954554.88 rows=395455488 width=170)
-> XN Seq Scan on tmp_accumulate ar (cost=0.00..3954554.88 rows=395455488 width=170)
Данные распределяются равномерно по всем узлам в соответствии с рисунком. Однако в каждом узле больше данных.
Я хочу знать, есть ли лучший метод обработки перекоса данных при объединении в Redshift?