MapJoin基本的几种方式:
Common Mapjoin:
hive.ignore.mapjoin.hint=true;#虽然现在可以自动转化mapjoin,但还是建议设成true,可以在需要特殊处理人为转化为mapjoin。
hive.auto.convert.join=true;hive.mapjoin.smalltable.filesize=250000000;
N-way join:
hive.auto.convert.join.noconditionaltask=true;#开启多路join加载到map中的开关。hive.auto.convert.join.noconditionaltask.size=250000000;#当n-1个表的总和小于等于该值时启动n-way mapjoin
Tips:多表在一个job连接时,大表放在后/*+STREAMTABLE*/(a)a为大表,利用reduce buffer减小内存消耗(同key,不同key多表连接时也是大表放在 后减小io)。
Sort Merge Bucket Join(MapJoin或者非MapJoin):
set hive.auto.convert.sortmerge.join=true;#是否当连接的两个表满足smb条件时(有序的分桶)自动采用sbmJoin(分桶Join,M or R)set hive.auto.convert.sortmerge.join.to.mapjoin=true;#当上面的参数为true时(两个都做了分桶32个...且sorted的表做连接时),但是join的表中有相对小的表时,是否将smb转为mapjoin。
set hive.auto.convert.sortmerge.join.bigtable.selection.policy=org.apache.hadoop.hive.ql.optimizer.AvgPartitionSizeBasedBigTableSelectorForAutoSMJ; #选择大表的策略
set hive.optimize.bucketmapjoin = true;#强制在Map端做bucket join
set hive.optimize.bucketmapjoin.sortedmerge = true;#强制在Map端做Sorted bucket Join
在两个表都很大时,建议每个表都要做分桶和排序(才能使用SMBJoin):
建表语句类似:
CREATE TABLE a(key INT, othera STRING) CLUSTERED BY(key) INTO 32 BUCKETS
SORTED BY(key)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' COLLECTION ITEMS TERMINATED BY '\002' MAP KEYS TERMINATED BY '\003' STORED AS SEQUENCEFILE;
在向表导入数据时,需要设置:
set Hive.enforce.bucketing = true;
set hive.enforce.sorting = true;
Shew join:
set hive.optimize.skewjoin=true;#join倾斜优化开关set hive.skewjoin.key=100000;#判断倾斜的阈值
hive.map.aggr=true
Map到Reduce的Shuffle阶段的倾斜:
hive.groupby.skewindata=true
/**有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
如果确认业务需要这样倾斜的逻辑,考虑以下的优化方案:
1、对于join,在判断小表不大于1G的情况下,使用map join
2、对于group by或distinct,设定 hive.groupby.skewindata=true*/