- join操作的理解
- join操作的优化
- spark的join操作
一、spark的join操作
1 概念理解
https://www.iteblog.com/archives/9870.html
'
2 Spark Join Hints
http://https://www.iteblog.com/archives/9874.html
'
3 broadcast join
1. broadcast不一定快
https://www.iteblog.com/archives/9837.html
2. 不起作用可能原因
1) 广播的名字不对,有别名时要广播表的别名;
2) 最好显示的指明广播join /*+ broadcast(bb) */
'
二、join的优化
1. join前过滤掉无效数据
2. 调整on条件的顺序
3. 使用广播join
4. 调整数据结构
降低join的数据量
每天活跃A表: 主键ID、应用名pkg、其它维度值, 数据量-300W
全量激活B表: 主键ID、应用名pkg、其它维度值, 数据量-370亿
聚合A表当天活跃中是当天激活的数据.
-- 常规做法
select
aa.country
,count(distinct id) as cnt
from A aa
join B bb
on aa.id = bb.id and aa.pkg = bb.pkg
group by
aa.country
;
-- 改进做法, 用数据结构降低数据量
select
aa.country
,count(distinct id) as cnt
from A aa
join ( -- 可以极大缩小数据量, 且数组元素不能过多
select
gazj
,collect_list(pkg) as pkgs
from B
group by
aa.gazj
) bb
on aa.id = bb.id and array_contains(bb.pkgs, aa.pkg)
group by
aa.country
;
三、数据倾斜
1. 膨胀数据
表A数据倾斜并且数据量大, 表B数据量较小
select
aa.id
,aa.name
,bb.age
from ( -- 大表增加一个(1-5)的随机值
select
id
,name
,ceil( rand()*5 ) as rnd_k
from
A
where
dt='${ds_nodash}'
) aa
join ( -- 小表数据膨胀5倍
select
id
,age
,explode(array(1, 2, 3, 4, 5)) as rnd_k
from
B
where
dt='${ds_nodash}'
) bb
on aa.id = bb.id and aa.rnd_k = bb.rnd_k
;
四、过滤条件
1. 条件在where上
1 存在问题
left join : 右表过滤放在where上, join会变成内关联;
right join: 左表过滤放在where上, join会变成内关联;
full join : 右表过滤放在where上, join会变成右关联; 左表过滤放在where上, join会变成左关联; 左右表过滤都在where上, join会变成内关联;
2 解决办法
子查询: 过滤条件放在子查询中
on子句: 过滤条件放在on上