大表x小表

这里可以利用mapjoin,SparkSQL中也有mapjoin或者使用广播变量能达到同样效果,此处描述HQL

// 开启mapjoin并设定map表大小

set hive.auto.convert.join.noconditionaltask = true;
set hive.auto.convert.join.noconditionaltask.size = ;

// 大表 join 小表

select * from big_table join small_table on big_table.id=small_table.id
原理:将小表加载进入节点容器内存中,大表可以直接读取节点容器内存中的数据进行匹配过滤

大表x大表

小表可以放进内存,大表则不行。尽量避免大表x大表的执行需求。如果确认有此需求,可以参考以下方法

1.尝试将大右表自我join成为一张宽表

// 利用右表的唯一属性自我join

select id, case when type='food' then  else  as type_tag,case when
sale_type='city' then sales else null as sale_amount from group by id

2.尝试先将大表按照主键分桶后join

create table new_left as select * from left_table cluster by id
create table new_right as select * from right_table cluster by id
select * from new_left join new_right on new_left.id=new_right.id

3.根据数据大小量级合理增加reduce数量,reduce不宜设置过大

// hadoop2代

set mapreduce.job.reduces=;

4.利用ORC bloomfilter, 大幅度提高join效率

注:parquet bloomfilter在开发中
// 建立orc表

create table default.right_orc stored as orcfile TBLPROPERTIES
('orc.compress'='SNAPPY',
'orc.create.index'='true',
'orc.bloom.filter.columns'='id')
as select * from right_table

// 使用新表join

select * from left_orc join right_orc on left_orc.id=righ_orc.id

5.调整内存限制

join时容易造成节点OOM,导致任务失败,可以尝试以下方法:
map阶段OOM,适当增加map阶段内存 set mapreduce.map.memory.mb=3096
reduce阶段OOM,适当增加reduce阶段内存 set mapreduce.reduce.memory.mb=4096
注: 默认执行引擎为mr,如果是TEZ,参考tez优化部分
6.善用explain/analyze
使用explain和analyze分析HQL语句和表,试图从中找出实际数据中可以优化的部分,这里和数据强关联,需要根据实际数据考量
7.数据预处理。
将部分join放入离线计算任务,减少业务join的时间

整理自apache spark技术交流社区

05-11 22:42