hive几种join方式

hive处理表关联时由于数据量以及数据倾斜等问题会导致计算性能差甚至任务失败,下面记录一下hive的几种关联方式。


1.common join

普通连接,在SQL中不特殊指定连接方式使用的都是这种普通连接。

缺点:性能较差

优点:操作简单,普适性强

2.map join

map端连接,与普通连接的区别是这个连接中不会有reduce阶段存在,连接在map端完成

适用场景:大表与小表连接,小表数据量应该能够完全加载到内存,否则不适用

优点:在大小表连接时性能提升明显,hive 0.6 的时候默认认为写在select 后面的是大表,前面的是小表, 或者使用 /*+mapjoin(map_table) */ 提示进行设定. hive 0.7 的时候这个计算是自动化的,它首先会自动判断哪个是小表,哪个是大表,这个参数由(hive.auto.convert.join=true)来控制. 然后控制小表的大小由(hive.smalltable.filesize=25000000L)参数控制(默认是25M),当小表超过这个大小,hive 会默认转化成common join。

缺点:使用范围较小,只针对大小表且小表能完全加载到内存中的情况

3.bucket map join

分桶连接:hive 建表的时候支持hash 分区通过指定clustered by (col_name,xxx ) into number_buckets buckets 关键字.当连接的两个表的join key 就是bucket column 的时候,就可以通过

hive.optimize.bucketmapjoin= true

来执行该优化策略。

原理:通过两个表分桶在执行连接时会将小表的每个分桶映射成hash表,每个task节点都需要这个小表的所有hash表,但是在执行时只需要加载该task所持有大表分桶对应的小表部分的hash表就可以,所以对内存的要求是能够加载小表中最大的hash块即可。

注意点:小表与大表的分桶数量需要是倍数关系,这个是因为分桶策略决定的,分桶时会根据分桶字段对桶数取余后决定哪个桶的,所以要保证成倍数关系。

优点:比map join对内存的要求降低,能在逐行对比时减少数据计算量(不用比对小表全量)

缺点:只适用于分桶表

4.skew join

倾斜连接,主要针对数据倾斜的情况优化

//指定每个reducer处理的数据量大小
hive.exec.reducers.bytes.per.reducer = 1000000000
//开启倾斜优化
set hive.optimize.skewjoin = true;
//设置数据条数(每个reduce数据条数上线) 
set hive.skewjoin.key = skew_key_threshold (default = 100000)

优点:处理倾斜数据可以均衡各reduce阶段的数据量

5.left semi join

左半连接:hive中对in和not in的支持不够且该操作效率太低所以提供了替代操作left semi join

功能有限,不过多讨论。

你可能感兴趣的:(hive)