select a.id, a.puid, a.os, a.dm, a.cbn, a.cbv, a.area, a.dis, case when b.sex is not null and b.sex <> '' and b.sex <> 'null' then b.sex else a.sex end as sex, -- 性别 if(b.age > 0 ,b.age,a.age) as age, -- 年龄 a.carr, a.eb, a.inc, a.ft, a.ftv, a.fpage, a.lt, a.ltv, a.chal, a.tday, a.tn, a.tt, a.tp, a.trkw, a.tclk, if(c.mobile >0 ,c.mobile,a.cpn) as cpn, case when d.email is not null and d.email <> '' and d.email <> 'null' then d.email else a.mail end as mail from DD_B_Basic_U3_Web_User_Profile a left outer join DD_B_Basic_U3_1_SexAge b on a.puid = b.uid left outer join DD_B_Basic_U3_1_mobile c on a.puid = c.uid left outer join DD_B_Basic_U3_pspt_Email d on a.puid = d.puid where a.dt = '20151117'
一张大表:DD_B_Basic_U3_Web_User_Profile
三张小表:DD_B_Basic_U3_1_SexAge DD_B_Basic_U3_1_mobile DD_B_Basic_U3_pspt_Email
一张大表left join三张小表,在join的时候出现了数据倾斜,一般join产生的数据倾斜可以把大表作为基表,然后通过map side join来解决,直接去掉reduce阶段,这样就不会卡在reduce 99%的问题上了。
在hive中可以调整hive.auto.convert.join.noconditionaltask.size这个参数来指定map side join触发的最大阀值,调大这个值,直到sql explain的时候出现如下 map reduce local work操作的时候,恭喜你现在的sql已经编程map side join了。
这个参数的设置因量力而行,不宜设置太大,默认是10M,根据自己内存的大小来设置,这里我改成了60M之后我的SQL变成了map side join了。如果两个大表join出现数据倾斜了,而任何一张大表都大到无法装载在内存中的时候,就不能采用这种方式了。