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 DELIMITEDFIELDS 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*/