核心思想:把Hive SQL当作Mapreduce程序去优化
以下SQL不会转成Mapreduce来执行
  1. select仅查询本表字段
  2. where仅对本表字段做条件过滤
Explanin 显示执行计划
explain [extended] query_sql;
-- extended 显示更详细

Hive运行方式
  • 本地模式
  • 集群模式
开启本地模式
计算任务 小 时:

set hive.exec.mode.local.auto=true;
注意:
hive.exec.mode.local.inputbytes.max
                --  默认值为128M
-- 表示加载文件的最大值,若大于改配置值仍会以集群方式运行
并行计算
开启并行计算模式
set hive.exec.parallel=true;
注意:
hive.exec.parallel.thread.number
-- 一次计算中允许并行执行的job个数的最大值
严格模式
set hive.mapred.mode=strict;
-- 默认为 nonstict非严格模式
查询限制
1、对于分区表,必须添加where对于分区字段的条件过滤
2、order by语句必须包含limit输出限制
3、限制执行笛卡尔积的查询
Hive排序
order by 
    对于查询结果做全排序,只允许有一个reduce处理
    当数据量较大时,应慎用,严格模式下必须结合limit来使用
sort by 
    对单个reduce的数据进行排序
            sort by不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只会保证每个reducer的输出有序,并不保证全局有序。
            sort by不同于order by,它不受hive.mapred.mode属性的影响,sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by你可以指定执行的reduce个数(通过set mapred.reduce.tasks=n来指定),对输出的数据再执行归并排序,即可得到全部结果。
distribute by
            distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。        
            sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。
    注:Distribute by和sort by的使用场景
        1.Map输出的文件大小不均。
        2.Reduce输出文件大小不均。
        3.小文件过多。
        4.文件超大。
cluster by
    相当于 sort by + distribute by 
    cluster by 不能 通过asc desc的方式指定排序规则,排序只能是倒序排序
    可通过 distribute by column sort by column asc|desc  的方式
Hive Join 
1.  Join计算时,将小表(驱动表)放在join的左遍
2.  Map join: 在Map端完成join
两种方式
1、SQL方式,在SQL语句中添加MapJoin标记
语法:
select /*+ mapjoin(smallTbl) */ smallTbl.key,bigTbl.value 
	from smallTbl join bigTbl on smallTbl.key = bigTbl.key;
2、开启自动的MapJoin
set hive.auto.convert.join=true;
-- 该参数为true,hive自动对左边的表统计量,如果时小表就加入内存,即对小表mapjoin
相关参数
hive.mapjoin.smalltable.filesize
-- 大表小表判断的阈值,如果表的大小小于该值就会被加载到内存
hive.ignore.mapjoin.hint
-- 默认值true,是否忽略mapjoin hint即sql中的mapjoin标记
hive.auto.convert.join.noconditionnoltask
-- 默认值true,将普通的join转化为普通的mappjoin时,是否将对各mapjoin转化为一个mapjoin
hive.auto.convert.join.onconditionaltask.size
-- 将多个mapjoin转化为一个mapjoin时,其表的最大值
Map-side聚合
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
--   (两次mapreduce)
控制hive中map和reduce的数量
map数量相关参数
mapred.max.split.size
--  一个split的最大值,即每个map处理文件的最大值
mapre.min.split.size.per.node
 --  一个节点上split的最小值
mapred.min.split.size.per.rack
 --  一个机架上split的最小值
reduce数量相关参数
mapred.reduce.tasks
--  强制指定reduce任务的数量
hive.exec.reduces.bytes.per.reducer
--  每个reduce任务处理的数据量
hive.exec.reducers.max
 --  每个任务最大的reduce数量
JVM重用
类似线程池
使用场景:
1、小文件过多
2、task个数过多
set mapred.job.reuse.jvm.num.tasks=n;
-- n为task插槽个数
缺点:设置后,task插槽会一直占用资源,无论是否有task执行
知道所有task即整个job全部执行完成后,才会释放所有task插槽资源



添加新评论