大表x小表
這里可以利用mapjoin,SparkSQL中也有mapjoin或者使用廣播變量能達到同樣效果,此處描述HQL
// 開啟mapjoin並設定map表大小
set hive.auto.convert.join.noconditionaltask = true; set hive.auto.convert.join.noconditionaltask.size = 10000000;
// 大表 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 0 else 1 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=200;
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技術交流社區