转载请注明出处:https://blog.csdn.net/l1028386804/article/details/80165054
场景: 如日志中,常会有信息丢失的问题,比如全网日志中的 user_id,如果取其中的 user_id和 bmw_users 关联,会碰到数据倾斜的问题。
解决方法 1: user_id 为空的不参与关联
Select * From log a
Join bmw_users b
On a.user_id is not null
And a.user_id = b.user_id
Union all
Select * from log a
where a.user_id is null;
解决方法 2: 赋与空值分新的 key 值
Select *
from log a
left outer join bmw_users b
on case when a.user_id is null then concat(‘dp_hive’,rand() ) else a.user_id = b.user_id end;
结论: 方法2比方法1效率更好,不但 io 少了,而且作业数也少了。方法 1 log 读取两次, jobs是 2。方法 2 job 数是 1 。这个优化适合无效 id(比如-99,’’,null 等)产生的倾斜问题。把空值的 key 变成一个字符串加上随机数,就能把倾斜的数据分到不同的 reduce 上 ,解决数据倾斜问题。附上 hadoop 通用关联的实现方法(关联通过二次排序实现的,关联的列为 parition key,关联的列 c1 和表的 tag 组成排序的 group key,根据parition key分配reduce。同一reduce内根据 group key 排序)。
Select * from s8_log a
Left outer join r_auction_auctions b
On a.auction_id = cast(b.auction_id as string);
select * from
(
select w.id, w.time, w.amount, i1.name, i1.loc, i1.cat
from w left outer join i sampletable(1 out of 2 on id) i1
)
union all
(
select w.id, w.time, w.amount, i2.name, i2.loc, i2.cat
from w left outer join i sampletable(1 out of 2 on id) i2
) )
;
以下语句实现了 left outer join 逻辑:
select t1.id, t1.time, t1.amount,
coalease(t1.name, t2.name),
coalease(t1.loc, t2.loc),
coalease(t1.cat, t2.cat)
from (
select w.id, w.time, w.amount, i1.name, i1.loc, i1.cat
from w left outer join i sampletable(1 out of 2 on id) i1
) t1 left outer join i sampletable(2 out of 2 on id) t2;
上述语句使用 Hive 的 sample table 特性对表做切分。