Hive的join方式

Hive的三种join方式:

Common/Shuffle/Reduce Join(正常/一般情况)
Map Join(大小表join、不等值join、结合union all) 
SMB(Sort-Merge-Buket) Join(大表join大表)

Shuffle Join

  Shuffle Join在Hive中也叫Common Join或Reduce Join。如果两边数据量都很大,它会进行把相同key的value合在一起,然后再去组合。

Map Join

1) 大小表连接
  如果一张表的数据很大,另外一张表很少(<1000行),那么可以将数据量少的那张表放到内存里面,在map端做join。Hive支持Map Join,用法如下:

select / *+ MAPJOIN(time_dim) */ count(1) from 
store_sales join time_dim on (ss_sold_time_sk = t_time_sk) 

2) 需要做不等值join操作(a.x < b.y或者a.x like b.y等)
  这种操作如果直接使用join的话语法不支持不等于操作,Hive语法解析会直接抛出错误。如果把不等于写到where里会造成笛卡尔积,数据异常增大,速度会很慢甚至任务无法跑成功。根据map join的计算原理,map join会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配。这种情况下即使笛卡尔积也不会对任务运行速度造成太大的效率影响。而且Hive的where条件本身就是在map阶段进行的操作,所以在where里写入不等值比对的话,也不会造成额外负担。

select / *+ MAPJOIN(a) */ 
a.start_level, b.* 
from dim_level a 
join (select * from test) b 
where b.xx>=a.start_level and b.xx<end_level; 

3)map join结合UNIONALL
  某些情况下join特别慢,可以观察数据,取出特殊(数据特别多的)字段范围放在一组,并使用map join与维表关联,放入内存中,除此之外的数据存入另一组,使用普通join,最后union all放到一起。当设置为true的时候,Hive会自动获取两张表的数据,判定哪个是小表,然后放在内存中。设置:

set hive.auto.convert.join=true; 
select count(*) from store_sales join time_dim on (ss_sold_time_sk = t_time_sk) ;

SMB Join

  大表join大表时,SMB join会自动根据相同的字段进行类似分区分桶的操作,将大表拆成更小一点的表再进行join。设置:

set hive.auto.convert.sortmerge.join=true (默认是falseset hive.optimize.bucketmapjoin=true; 
set hive.optimize.bucketmapjoin.sortedmerge=true; 

你可能感兴趣的:(Hive)