Hive 优化
核心思想:把Hive SQL 当做Mapreduce程序去优化
以下SQL不会转为Mapreduce来执行(HDFS执行的)
select 仅查询本表字段
where 仅对本表字段做条件过滤
Explain 显示执行计划
explain extended select count(*) from psn;
strict 严格模式,防止误操作!
效率太低,要做限制
也很随意!
split map shuffle* reduce
竭尽全力去不经过shuffle
本地模式
开启本地模式:set hive.exec.mode.local.auto=true;
hive.exec.mode.local.auto.inputbytes.max
默认值为128M
,表示加载文件的最大值,若大于该配置仍会以集群方式来运行!
并行计算(速度快)
通过设置以下参数开启并行模式:set hive.exec.parallel=true;
注意:hive.exec.parallel.thread.number
一次SQL计算
中允许并行执行的job个数的最大值
严格模式下查询限制:
- 通过设置以下参数开启严格模式:
set hive.mapred.mode=strict;
(默认为:nonstrict
非严格模式) - 对于分区表,必须添加
where
对于分区字段的条件过滤; -
order by
语句(排序)必须包含limit
输出限制
; - 限制执行
笛卡尔积
的查询。
hive> select * from psn3; // 报错❎
FAILED: SemanticException [Error 10041]: No partition predicate found for Alias "psn22" Table "psn22"
hive> select * from psn3 where age=10 and sex='man'; // ✅
hive> select * from psn order by id desc;
FAILED: SemanticException 1:27 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error enc
ountered near token 'id'
hive> select * from psn order by id desc limit 5;
开启map-reduce操作!
Hive排序
-
Order By
- 对于查询结果做全排序,只允许有一个reduce
处理(当数据量较大时,应慎用。严格模式下,必须结合limit
来使用) -
Sort By
- 对于单个reduce
的数据进行排序 -
Distribute By
- 分区排序,经常和Sort By
结合使用 -
Cluster By
- 相当于Sort By + Distribute By
(可通过Cluster By
不能通过asc
、desc
的方式指定排序规则;distribute by column sort by column asc|desc
的方式)
Hive Join
-
Join
计算时,将小表(驱动表)放在join
的左边,执行效率高 -
Map Join
:在Map端完成Join
两种实现方式:
a.SQL
方式,在SQL
语句中添加MapJoin
标记(mapjoin hint
)
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
b. 开启自动的MapJoin
- 开启自动mapjoin:
set hive.auto.convert.join = true;
(该参数为true
时,Hive
自动对左边的表统计量,如果是小表就加入内存,即对小表使用Map join
)
相关配置参数:
-
hive.mapjoin.smalltable.filesize;
(大表小表判断的阈值,如果表的size小于该值则会被加载到内存中运行) -
hive.ignore.mapjoin.hint;
(默认值:true
;是否忽略mapjoin hint
即mapjoin
标记) -
hive.auto.convert.join.noconditionaltask;
(默认值:true
;将普通的join转化为普通的mapjoin
时,是否将多个mapjoin
转化为一个mapjoin
) -
hive.auto.convert.join.noconditionaltask.size;
(将多个mapjoin
转化为一个mapjoin
时,其表的最大值)
Map-Side聚合
通过设置以下参数开启在Map端的聚合:set hive.map.aggr=true;
相关配置参数:
-
hive.groupby.mapaggr.checkinterval
:map端group by
执行聚合时处理的多少行数据(默认:100000) -
hive.map.aggr.hash.min.reduction
:进行聚合的最小比例(预先对100000条数据做聚合,若聚合之后的数据量/100000的值大于该配置0.5,则不会聚合) -
hive.map.aggr.hash.percentmemory
:map
端聚合使用的内存的最大值 -
hive.map.aggr.hash.force.flush.memory.threshold
:map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush -
hive.groupby.skewindata
:是否对GroupBy
产生的数据倾斜做优化,默认为false
控制Hive中Map以及Reduce的数量
(1)Map数量相关的参数
-
mapred.max.split.size
一个split的最大值,即每个map
处理文件的最大值 -
mapred.min.split.size.per.node
一个节点上split
的最小值 -
mapred.min.split.size.per.rack
一个机架上split
的最小值
(2)Reduce数量相关的参数
-
mapred.reduce.tasks
强制指定reduce
任务的数量 -
hive.exec.reducers.bytes.per.reducer
每个reduce
任务处理的数据量 -
hive.exec.reducers.max
每个任务最大的reduce
数
Hive - JVM重用
通过set mapred.job.reuse.jvm.num.tasks=n;
来设置(n为task插槽个数)
缺点:设置开启之后,task
插槽会一直占用资源,不论是否有task
运行,直到所有的task
即整个job
全部执行完成时,才会释放所有的task插槽资源!
适用场景:
-
小文件个数
过多 -
task个数
过多
参考资料
Hadoop集群上搭建Hive
Hive建表并加载数据
Hive参数和动态分区
Hive分桶
Hive视图和索引
Hive运行方式和授权
网友评论