目录
- 执行顺序
- explain计划
- 优化
- 优化要点
- 4.1 让服务器尽可能的多做事情,以最高系统吞吐量为目标
- 4.2 让服务器**尽量少做事情,走最优的路径,以资源消耗最少为目标
- 4.2.1 map join的使用
- 4.2.2 注意小文件的问题
- 4.2.3 注意数据倾斜
- 4.2.4 善用**multi insert和union all
- 4.2.5 参数设置的调优
执行顺序
hive语句和mysql都可以通过 explain+代码 查看执行计划,这样就可以查看执行顺序
**SQL语句书写顺序:**
select … from … where … group by … having … order by …
**SQL语句执行顺序:**
from … where … group by … having … select … order by …
from … on … join … where … group by … having … select … distinct … order by … limit
**hive语句执行顺序:**
from … where … select … group by … having … order by …
explain计划
基于MapReduce引擎
Map阶段:
1.执行from加载,进行表的查找与加载
2.执行where过滤,进行条件过滤与筛选
3.执行select查询:进行输出项的筛选
4.执行group by分组:描述了分组后需要计算的函数
5.map端文件合并:map端本地溢出写文件的合并操作,每个map最终形成一个临时文件。
然后按列映射到对应的reduceReduce阶段:
Reduce阶段:
1.group by:对map端发送过来的数据进行分组并进行计算。
2.select:最后过滤列用于输出结果
3.limit排序后进行结果输出到HDFS文件
转载自:添加链接描述
具体介绍如下
**stage1的map阶段**
TableScan:from加载表,描述中有行数和大小等
Filter Operator:where过滤条件筛选数据,描述有具体筛选条件和行数、大小等
Select Operator:筛选列,描述中有列名、类型,输出类型、大小等。
Group By Operator:分组,描述了分组后需要计算的函数,keys描述用于分组的列,outputColumnNames为输出的列名,可以看出列默认使用固定的别名_col0,以及其他信息
Reduce Output Operator:map端本地的reduce,进行本地的计算,然后按列映射到对应的reduce
**stage1的reduce阶段Reduce Operator Tree**
Group By Operator:总体分组,并按函数计算。map计算后的结果在reduce端的合并。描述类似。mode: mergepartial是说合并map的计算结果。map端是hash映射分组
Select Operator:最后过滤列用于输出结果
File Output Operator:输出结果到临时文件中,描述介绍了压缩格式、输出文件格式。
stage0第二阶段没有,这里可以实现limit 100的操作。
优化
- 限制分区。
- 连接表时使用相同的关键词,这样只会产生一个job。
- 减少每个阶段的数据量,只选出需要的,在join表前就进行过滤。在实习时,有时候为了减少代码量,包含了多余的字段,导致速度会变慢一些。
- map端聚合。在上data mining的时候,写mapreduce程序,有时候会在mapper和reducer之间加一个combinator,提前进行合并以减少通信成本。
-
大表放后面。在执行多个表时,会先将前面的表放到缓存,因此最好将大表放到最后。
hive.map.aggr=true; // 用于设定是否在 map 端进行聚合,默认值为真 hive.groupby.mapaggr.checkinterval=100000; // 用于设定 map 端进行聚合操作的条目数
转载自:添加链接描述
学习链接:添加链接描述
优化要点
总体两种思想:
4.1 让服务器尽可能的多做事情,以最高系统吞吐量为目标
比如:
- (1) 启动一次job尽可能的多做事情,一个job能完成的事情,不要两个job来做
通常来说前面的任务启动可以稍带一起做的事情就一起做了,以便后续的多个任务重用,与此紧密相连的是模型设计,好的模型特别重要. - (2) 合理设置reduce个数
reduce个数过少没有真正发挥hadoop并行计算的威力,但reduce个数过多,会造成大量小文件问题,数据量、资源情况只有自己最清楚,找到个折衷点, - (3) 使用参数控制在同一个sql中的不同的job是否可以同时运行,提高作业的并发
4.2 让服务器**尽量少做事情,走最优的路径,以资源消耗最少为目标
4.2.1 map join的使用
若其中有一个表很小使用map join,否则使用普通的reduce join,注意hive会将join前面的表数据装载内存,所以较小的一个表在较大的表之前,减少内存资源的消耗
4.2.2 注意小文件的问题
在hive里有两种比较常见的处理办法
第一是使用Combinefileinputformat,将多个小文件打包作为一个整体的inputsplit,减少map任务数
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=256000000
set Mapred.min.split.size.per.rack=256000000
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
第二是设置hive参数,将额外启动一个MR Job打包小文件
hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False
hive.merge.size.per.task = 256*1000*1000 合并文件的大小
4.2.3 注意数据倾斜
在hive里比较常用的处理办法
第一通过=true控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到reduce做次预汇总,减少某些key值条数过多某些key条数过小造成的数据倾斜问题
第二通过 = true(默认为true)在Map端做combiner,假如map各条数据基本上不一样, 聚合没什么意义,做combiner反而画蛇添足,hive里也考虑的比较周到通过参数 = 100000 (默认)=0.5(默认),预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合
第三对实际key数据分布预先统计根据实际情况进行调优。
举例:
null值较多,分布在一个reduce调优
Select*
from log a
left outer join bmw_users b
on case when a.user_id is null thenconcat(‘dp_hive’,rand() ) else a.user_id end = b.user_id;
再比如做reduce join时关联某些值特别多,我们可以先count采样下,知道有哪几个值特别斜,用union all
这些值的单独用mapjoin,再 union 起来
4.2.4 善用**multi insert和union all
- multi insert适合基于同一个源表按照不同逻辑不同粒度处理插入不同表的场景,做到只需要扫描源表一次,job个数不变,减少源表扫描次数
- union all用好,可减少表的扫描次数,减少job的个数,通常预先按不同逻辑不同条件生成的查询union all后,再统一group by计算,不同表的union all相当于multiple inputs,同一个表的union all,相当map一次输出多条
4.2.5 参数设置的调优
如可针对特定job设置特定参数,比如jvm重用,reduce copy线程数量设置(适合map较快,输出量较大).
如果任务数多且小,比如在一分钟之内完成,减少task数量以减少任务初始化的消耗。可以通过配置JVM重用选项减少task的消耗
转载自:添加链接描述
待办:/discuss/328069?type=post&order=jing&pos=&page=1&channel=-2&source_id=search_post&subType=2