Hive优化策略
架构层面(高效,全局或局部)
分表
合理利用中间结果表,重视查过就丢的资源浪费,导致hadoop的IO负载瓶颈
对于常用的复杂或低效统计统一给出,以避免上层作业过多计算
合理设计表分区,静态分区和动态分区
HQL语法层面(中低效,job内)
执行计划
谓词上移,如where提到关联表去完成
左表是小表,右表是大表
用group by替换count(distinct),因为可以被多分配reduce数
用sort by替换order by,理由也是可分配多个reduce数
如果要用order by,加上limit进行限制
创建表是用parquet格式去保存,因为该格式会进行列式压缩,效果较好
对于大表要考虑分库,分区,分表
尽量不用select ,而是用具体列名替换
HIVE参数层面(全局)
太暴力,很少用,有时会起到好效果
Hive语法优化
合理控制map和reduce数
合并小文件
避免数据倾斜,解决数据倾斜
减少job数(合并job,大job分拆…)
1.Map数和reduce数
1.1map数
Map数过大
Map阶段输出文件太小,产生大量小文件
初始化和创建map的开销很大
Map数过小
文件处理或查询并发度小,job时间执行过长
大量作业时,会堵塞集群
通常情况下,作业会通过input文件产生一个或多个map数
主要决定因素有:input文件数和input文件大小
Ex:
1)假设input目录下有1个文件a,大小为780mb,则hadoop会将a文件分为7个块(6个128mb和1个12mb的块,一个block是128mb),从而产生7个map数
2)假设input目录下有3个文件a,b,c,大小分别为10mb,20mb,130mb,则hadoop会分隔为4个块(10mb,20mb,128mb,2mb),从而产生4个map数
两种方式控制map数:即减少map数和增加map数
减少map数可通过合并小文件来实现,这点是对文件源
增加map数可通过控制上一个job的reducer数来控制(一个sql中join多个表会分解为多个mapreduce)
小文件进行合并:
Map阶段hive自动对小文件进行合并
对应参数和默认值:
Set hive.merge.mapfiles = true #在map-ONLY的任务结束时合并小文件
Set hive.merge.mapredfiles = true #默认是false,true时在map-reduce的任务结束时合并小文件
Set hive.merge.size.per.task = 25610001000 #合并文件大小
Set mapred.max.split.size = 256000000 # 每个map最大分割大小