Hive调优

1、Fetch 抓取

Fetch 抓取是指,Hive 中对某些情况的查询可以不必使用 MapReduce 计算。
例如: SELECT * FROM employees;在这种情况下,Hive 可以简单地读取employee 对应的存储目录下的文件,然后输出查询结果到控制台。
在 hive-default.xml.template 文件中 hive.fetch.task.conversion 默认是 more,老版本 hive 默认是 minimal,该属性修改为 more 以后,在全局查找、字段查找、limit 查找等都不走mapreduce。

把 hive.fetch.task.conversion 设置成 none,然后执行查询语句,都会执行 mapreduce程序。
把 hive.fetch.task.conversion 设置成 more,然后执行查询语句,
如下查询方式都不会执行 mapreduce 程序

2、本地模式

set hive.exec.mode.local.auto=true  //开启本地模式

要求:默认数据小于128M,默认文件个数小于4,超过则会自动转换为Hadoop模式。也可以自行修改
数据和文件限制。

3、Join表的优化

空key过滤

insert overwrite table jointable
select n.* from nullidtable n left join ori o on n.id = o.id;

insert overwrite table jointable
select n.* from (select * from nullidtable where id is not null ) n //过滤空Key
left join ori o on n.id = o.id;

空Key转换

空key会集中到一个Reduce中,导致数据倾斜

insert overwrite table jointable
select n.* from nullidtable n left join ori b on n.id = b.id;

insert overwrite table jointable
select n.* from 
nullidtable n full join 
ori o 
on
case when n.id is null then concat('hive', rand()) else n.id end //如果o.id为null则分配一个随机数
= o.id;

总体时间会加长,但解决了数据倾斜的问题,保证MR能正常运行

Map Join

set hive.auto.convert.join = true; 默认为 true

大表小表的阈值设置(默认 25M 一下认为是小表):
set hive.mapjoin.smalltable.filesize=25000000; //可调高阈值来缩短时间
如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么Hive 解析器会将Join 操作转换成 Common Join,即:在 Reduce 阶段完成 join。
容易发生数据倾斜。可以用 MapJoin 把小表全部加载到内存在 map 端进行 join,避免 reducer 处理。

4、Group By

默认情况下,Map 阶段同一 Key 数据分发给一个 reduce,当一个 key 数据过大时就倾斜了
并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在Reduce 端得出最终结果

hive.map.aggr = true    //是否在 Map 端进行聚合,默认为True

hive.groupby.mapaggr.checkinterval = 100000  //在 Map 端进行聚合操作的条目数目

hive.groupby.skewindata = true   //有数据倾斜的时候进行负载均衡(默认是 false)

当选项设定为 true,生成的查询计划会有两个MR Job。
第一个MR Job 中,Map 的输出结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的Reduce 中,从而达到负载均衡的目的;
第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中
(这个过程可以保证相同的Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作

5、去重统计

COUNT DISTINCT (去重统计)使用先 GROUP BY 再 COUNT 的方式替换

select count(distinct id) from bigtable; 

select count(id) from (select id from bigtable group by id) a;

6、行列过滤

列处理:在 SELECT 中,只拿需要的列,如果有,尽量使用分区过滤,*不要用 SELECT ,要用的话加上limit
行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在 Where 后面,那么就会先全表关联,之后再过滤

7、动态分区

插入数据时,按字段分区【PARTITIONED BY (p_time)】

set hive.exec.dynamic.partition=true   //开启动态分区功能(默认 true,开启)
set hive.exec.dynamic.partition.mode=nonstrict   //设置为非严格模式
set hive.exec.max.dynamic.partitions=1000   //在所有执行 MR 的节点上,最大一共可以创建多少个动态分区
set hive.exec.max.dynamic.partitions.pernode=100 //节点的动态分区

insert into table dept_par partition(deptno)
select deptno,dname,loc from dept;  //发现会按照loc来分区,所以动态分区一定要把分区字段写在最后

8、MR优化

合理设置 Map 数
小文件进行合并
复杂文件增加 适量的Map 数
合理设置 Reduce 数
说的都是P话。。。。

9、并行执行

set hive.exec.parallel=true;  //打开任务并行执行
set hive.exec.parallel.thread.number=16; ////同一个 sql 允许最大并行度,默认为 8。

意思是,一堆任务执行时,某一个任务执行得很慢,系统就会再启动一个任务同时执行,先执行完的可以kill慢的进程。

10、严格模式

根据参数得
Cartesian Product. //限制笛卡尔积
No partition being picked up for a query. //除非 where 语句中含有分区字段过滤条件来限制范围,否则不允许执行
Comparing bigints and strings.
Comparing bigints and doubles.
Orderby without limit. //order by必须加limit

你可能感兴趣的:(Hive调优)