代码级别的调优

友情提示:小编扛着发烧写完这详细的总结,请一定要给一键三连呀各位大佬

explain 与 explain exented 优化

```powershell
explain select * from text1;
explain extended select * from text1;
explain extended
select
d.deptno as deptno,
d.dname as dname
from dept d
union all
select
d.dname as dname,
d.deptno as deptno
from dept d
;
explain :只有对HQL语句的解释
explain extended :对HQL语句解释,以及抽象语法树的生成
stage:相当于一个job,一个stage可以是limit、也可以是一个子查询,也可以是group by等
hive默认一次只执行一个stage,但是如果stage之间依赖,将可以并行执行。
任务越复杂,Hql代码越复杂,stage数量越多,程序运行的时间越长

join 优化

hive的查询永远都是小表(结果集)驱动大表(结果集)
hive中的on连接只能是等值连接
注意点:hive是否配置普通的join转化为map端的job,以及map join小表文件的阈值

limit优化

```powershell
hive.limit.max.row.size=100000
hive.limit.optimize.limit.file=10
hive.limit.optimize.enable=false(如果limit较多时可以开启)
hive.limit.optimize.fetch.max=50000

本地模式

hive.exec.mode.local.auto=false(建议开启)
hive.exec.mode.local.inputbytes.max=134217728
hive.exec.mode.local.input.files.max=4

并行执行

hive.exec.parallel=false(建议打开)
hive.exec.parallel.number=8

严格模式

```powershell
hive.mapred.mode=nonstrict

mapper与reducer的个数优化

不是mapper与reducer的数据越多越好,也不是越少越好
合并小文件处理(将输入类设置为:CombineTextInputFormat),通过配置将小文件合并处理

```powershell
mapred.max.split.size=256000000
mapred.min.split.size.per.node=1
mapred.min.split.szie.per.rack=1
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
set mapreduce.job.reduces=10
hive.exec.reducers.max=1009

配置JVM重用

set mapreduce.job.jvm.numtasks=1
set mapred.job.reuse.jvm.num.tatks=1

数据倾斜

数据倾斜:由于Key分配不均匀,造成数据向某一方面发生偏离的现象
本身数据就存在倾斜
join语句容易造成倾斜
count(distinct col) 很容易造成倾斜
group by 也可能会造成倾斜
细节详解:Group By 聚合倾斜:分组的维度过少,每个维度的值过多,导致处理某值的 reduce
耗时很久;对一些类型统计的时候某种类型的数据量特别多,其他的数据类型特别少。
当按照 类型进行 group by 的时候,会将相同的 group by 字段的 reduce 任务需要的数据拉取
到同 一个节点进行聚合,而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这个 
reduce 还没有计算完成,其他的节点一直等待这个节点的任务执行完成,所以会一直看到
 map 100% reduce99%的情况;

解决方案:
找到造成倾斜的key ,然后再通过hql语句避免
hive.map.aggr=true(这个配置代表开启 map 端聚合)
hive.groupby.skewindata=false(建议开启,(选项设定为 true,生成的查询计划会有两个 MR 
Job。 当第一个 MR Job 中,Map 的输出结果结合会随机分布到 Reduce 中,
每个 Reduce 做部分 聚合操作,并输出结果)
hive.optimize.skewjoin=false

索引是一种hive的优化

要想索引在查询时生效,还的设置使用索引。默认是不使用的
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
SET hive.optimize.index.filter=true;
SET hive.optimize.index.filter.compact.minsize=0;

分区分桶也是Hive的优化–建议按照实际情况多使用分区分桶
job的数量:

一个查询就会触发一个job,通常情况下一个子查询 ,一个 limit ,group by ,join均会产生一个job ,因此我们在编写HQL语句,应尽量精简HQL语句复杂度,避免不必要的job操作影响性能

口述级小技巧总结

1.在排序中,我们使用的是sortBy,它是基于索引,效率高于order by

2.我们在分区的时候采用静态分区,静态分区只是读取配置文件,而动态分区需要重复的读取其它分区的标识,大量的制造了不必要的开销

3.在对待groupBy的数据倾斜的方面,我们设置hive.group.sviWind=ture,这表明它会自动进行负载均衡,去除了数据倾斜的问题

4.hive比较擅长处理大文件,大文件会有效的减少过多job,task的创建,这里我们使用UDF和UDAF来处理数据。UDF是单一处理,解决BUG,UDAF是多行处理,还有UDTF,这里我们不用还是说简单说一下

是单一输入,多行输出。

5.减少job和task的数量,我们使用表的链接。

6.小表去join大表

7.大表join大表,过滤空key

8.设置并行数

9.关闭推测执行

10.设置索引

11.在where字句中增加分区过滤器

12.当表为分区表时,where字句后没有分区字段和限制时,不允许执行

13.当使用order by语句时,必须使用limit字段,因为order by 只会产生一个reduce任务

14.如果所有表中有一张表足够小,则可置于内存中,这样在和其他表进行连接的时候就能完成匹配,省略掉reduce过程。设置属性即可实现,set hive.auto.covert.join=true; 用户可以配置希望被优化的小表的大小 set hive.mapjoin.smalltable.size=2500000; 如果需要使用这两个配置可置入$HOME/.hiverc文件中

15.同一种数据的多种处理:从一个数据源产生的多个数据聚合,无需每次聚合都需要重新扫描一次。

例如:insert overwrite table student 
      select * 
      from employee; 
      insert overwrite table person 
      select * from employee;
可以优化成:
      from employee insert overwrite table student 
      select * insert overwrite table person select *

16.当使用order by语句时,必须使用limit字段,因为order by 只会产生一个reduce任务

17.推测式任务,也叫做Speculative task。它是一种以空间换时间的策略。
当所有task都开始运行之后,任务对应的ApplicationMaster会统计所有任务的平均进度,如果某个task所在的task node机器配置比较低或者CPU load很高(原因很多),导致任务执行比总体任务的平均执行要慢,
此时AM会启动一个新的任务(Speculative task),原有任务和新任务哪个先执行完就把另外一个kill掉,
这也是我们经常在RM页面看到任务执行成功,但是总有些task被kill,就是这个原因。
目的:是通过加快获取单个 task 的结果以及进行侦测将执行慢的 TaskTracker 加入到黑名单的方式来提高整体的任务执行效率

修改hive 配置实现
set hive.mapred.reduce.tasks.speculative.execution=true;

18.不执行mapreduce,提高速度
设置的三种方式:

方法一:

set hive.fetch.task.conversion=more;
方法二:

bin/hive --hiveconf hive.fetch.task.conversion=more
方法三:
上面的两种方法都可以开启了Fetch任务,但是都是临时起作用的;如果你想一直启用这个功能,
可以在${HIVE_HOME}/conf/hive-site.xml


<property>

<name>hive.fetch.task.conversion</name>

<value>minimal</value>

<description>

Some select queries can be converted to single FETCH task minimizing latency.

Currently the query should be single sourced not having any subquery and should not have

any aggregations or distincts (which incurs RS), lateral views and joins.

1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only

2. more : SELECT, FILTER, LIMIT only (TABLESAMPLE, virtual columns)

</description>

</property>

19.大表【拆分子表】

1 背景
一个日志文件中,每一行记录,会有很多很多字段,四五十个字段很正常.实际分析中,常常使用少数
几个字段
2 方式
将原始的表中数据,依据业务需求提取出要分析的字段,数据放入到对应的业务表(子表)中,实际
的业务针对业务表进行分析。

20…选择使用Tez引擎

```powershell
Tez: 是基于Hadoop Yarn之上的DAG(有向无环图,Directed Acyclic Graph)计算框架。
它把Map/Reduce过程拆分成若干个子过程,同时可以把多个Map/Reduce任务组合成一个较大的
DAG任务,减少了Map/Reduce之间的文件存储。同时合理组合其子过程,也可以减少任务的运行时间

设置
hive.execution.engine = tez;
最后一个:单个作业最优不如整体最优