hive mapjoin 使用 和个人理解

遇到一个hive的问题,如下hive sql:


select t1.a,t1.b from table t1 join table2 t2  on ( t1.a=t2.a and t1.datecol=20110802)

该语句中B表有30亿行记录,t1表只有100行记录,而且t2表中数据倾斜特别严重,有一个key上有15亿行记录,在运行过程中特别的慢,而且在reduece的过程中遇有内存不够而报错。


为了解决用户的这个问题,考虑使用mapjoin,mapjoin的原理:

MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,而普通的equality join则是类似于mapreduce模型中的file join,需要先分组,然后再reduce端进行连接,使用的时候需要结合着场景;由于mapjoin是在map是进行了join操作,省去了reduce运行,效率也会高很多

这样就不会由于数据倾斜导致某个reduce上落数据太多而失败。于是原来的sql可以通过使用hint的方式指定join时使用mapjoin。

select /*+ mapjoin(t1)*/ t1.a,t1.b from table t1 join table2 t2  on ( t1.a=t2.a and f.ftime=20110802)


再运行发现执行的效率比以前的写法高了好多。



mapjoin还有一个很大的好处是能够进行不等连接的join操作,如果将不等条件写在where中,那么mapreduce过程中会进行笛卡尔积,运行效率特别低,这是由于equality join (不等值join操作有 >、<、like等如:a.x < b.y 或者 a.x like b.y) 需要在reduce端进行不等值判断,map端只能过滤掉where中等值连接时候的条件,如果使用mapjoin操作,在map的过程中就完成了不等值的join操作,效率会高很多。

例子:

select A.a ,A.b from A join B where A.a>B.a


Mapjoin 不能使用与 outer join

/work/tda/hive-0.9.0/bin/hive -e "use yunion; select  /*+ mapjoin(t1)*/ t2.juid from t_pvjoinvv t1 
left outer join
(select distinct juid from t_vvformat where start_date=20130306 and flag=1 and sourceid<3 ) t2
on t1.juid=t2.juid
where t1.start_date=20130306 
and  t1.pv_1stflag=1 
and t2.juid is null ;
" ;
抛出异常:
OK
Time taken: 1.957 seconds
FAILED: Error in semantic analysis: MAPJOIN cannot be performed with OUTER JOIN




简单总结一下,mapjoin的使用场景:

1. 关联操作中有一张表非常小

2.不等值的链接操作


结合着网上博客,加入自己理解。

你可能感兴趣的:(Hive)