🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 小表,大表join 将key相对分散,并且**数据量小的表放在join的左边**,这样可以有效减少内存溢出错误发生的几率. 再进一步使用Group让小的维度表(1000条以下的记录条数)先进内存.在map端完成reduce. 实际测试发现: 新版hive已经对小表join大表和大表join小表进行了优化,小表放在左边和右边已经没有明显区别. # 大表join大表 ## 空key过滤 有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够.此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在sql语句中进行过滤. ~~~ select n.* from (select * from nullidtable where id is not null) n left join ori o on n.id=o.id; ~~~ ## 空key转换 有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀的分到不同的reducer上 例如 不随机分布空null值 1. 设置5个reduce个数 ~~~ set mapreduce.job.reduces=5; ~~~ 2. join两张表 ~~~ select n.* from nullidtable n full join ori o on case when n.id is null then concat('hive', rand()) else n.id end = o.id; ~~~ 消除了数据倾斜,负载均衡reducer的资源消耗 # MapJoin 如果不指定MapJoin或者不符合MapJoin的条件,那么hive解析器会将join操作转换层commin join.即在reduce阶段完成join.容易发生数据倾斜.可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理 **开启mapjoin参数设置** * 设置自动选择MapJoin ~~~ //默认是true set hive.auto.convert.join=true; ~~~ * 大表小表的阈值设置(默认25M以下是小表) ~~~ set hive.mapjoin.smaltable.filesize=25000000 ~~~ **MapJoin工作机制** ![](https://box.kancloud.cn/482a3e05ffff8525e977d52db309b5ef_1076x778.png) 1. Task A,他是一个local task(在客户端本地执行task),负责扫描小表b的数据,将其转换成一个HashTabke的数据结构,并写入本地的文件中,之后将文件加载到DistributeCache中 2. Task B,该任务是一个没有Reduce的MR,启动MapTasks扫描大表a,在map节点,根据a的每一条记录去和DistributeCache中b表对应的HashTable关联,并直接输出结果 3. 由于MapJoin没有Reduce,所以由Map直接输出结果文件,有多少个Map Task,就有多少个结果文件