仅从SQL和表及参数层面简单总结22种Hive基础调优方式

本文从SQL语句优化、表设计调整、参数配置改善和资源管理四个方面,总结了22种Hive的基础调优方法,包括SQL查询的优化策略、表分区与倾斜的解决方案以及Hive执行性能的提升技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、SQL和table层面

1、column pruning(列裁剪)
    查询的时候需要哪些列,直接查这些列即可,不要全局查询。

2、partition pruning(分区裁剪)          
    查询的时候需要哪些分区,直接查这些分区即可,不要全局查询。

3、合理利用中间结果集
    SQL1包含:select a,b,c from xxx group ...   
    SQL2包含:select a,b,d from xxx group ....
    
    我们可以在sql1和sql2执行之前先创建临时表
            create temporary table tmp_1 as select a,b,c,dfrom xxx group ....
    然后在临时表的基础上执行SQL1和SQL2。

4、对表或分区进行分桶(大表join大表)
    2张表对于连接的字段进行分桶。
    处理左边表内某个桶的Mapper他知道右边表内对应的行在对应的桶内。
    因此Mapper只需要获取那个桶,然后取得数据进行JOIN 。 

5、多个join尽可能使用相同的连接键
    select t1.a,t2.a,t3.a from t1 
        join t2 on t1.key1=t2.key1 
        join t3 on t2.key1=t3.key1;
        #####连接条件相同,只有一个MR
    select t1.a,t2.a,t3.a from t1 
        join t2 on t1.key1=t2.key1 
        join t3 on t2.key2=t3.key2;
        #####连接条件不同,有两个MR

6、排序优化       
    Order By:在一个reducer上处理所有数据,虽然整体有序的,但不能并发执行,效率低。
    而且只有一个reducer,作业可能跑不出来,而且很可能数据倾斜。
    Sort By:排序操作在多个reducer上执行,整体无序(reducer间)但局部有序(reducer内)。
    Distributed By:按指定字段分发数据到reducer,相同的hash值到同一个reducer。
        我们经常使用distributed by id sort by score,来进行排序。
                相同id会到同一个reducer,各个reducer中通过name来排序。
    Clustered By:Sort By和Distribute By两个后接字段一致,即分发字段和排序字段是同一个字段,则
等同于使用clustered by ,但clustered by不能指定排序方式。


7、将reduce join转成map join 
    hive可以将小表(默认小于25000000bytes,即25mb为小表)加入内存,与map端的大表join,这称之为map join。
    语法:
        select  /*+ mapjoin(t1)*/  t1.key,  t2.value from  t1  join t2 on      t1.key=t2.key;
        #####t1为小表,t2为大表
    
    也可以自动让hive去判断是否转map join:
        set hive.auto.convert.join = true;
    当这个参数为true,hive会去判断左表是否超过25000000bytes,没超过则加入内存执行map join。

相关配置参数:
    hive.mapjoin.smalltable.filesize;  #####小表判断阈值,默认25000000byte
    hive.ignore.mapjoin.hint;######手动自动都开启时是否忽略手动指定的mapjoin,默认为true
    hive.auto.convert.join.noconditionaltask;####将多个mapjoin转化为一个mapjoin,默认true
    hive.auto.convert.join.noconditionaltask.size;#####mapjoin合并后表的最大大小


8、存储格式优化
    https://blog.youkuaiyun.com/pengzonglu7292/article/details/79463092

9、配置压缩
    https://blog.youkuaiyun.com/pengzonglu7292/article/details/79419021

结合8、9两点:
    如果配置压缩,就用parquet,压缩格式lzo。
    如果不配置压缩,就使用orc。


10、连接查询与子查询互转避免分组字段数据倾斜

2、参数层面

1、抓取策略
    Hive中对某些情况的查询不需要使用MapReduce计算,而仅仅是将数据抓取过来展现即可。

    hive.fetch.task.conversion
        #####参数取值none,minimal和more
    none:  禁用抓取策略。任何SQL都会执行mr。
    minimal:
        select * from emp where name='张三' limit 2;
        如果表emp没有分区,则以上SQL不会跑MR。
        如果表emp有分区,则必须还要指定具体分区。 
    more:
        select * from emp where name='张三' limit 2;
        表emp有没有分区,以上SQL都不会跑MR。
        新版本的默认策略。
    
2、本地模式
    在本地执行作业,避免作业提交到集群上任务分配与资源调度花费太多时间。
    仅适用于在非生产环境的小型job。

    hive.exec.mode.local.auto    
        #####是否开启本地模式,默认为false
    ive.exec.mode.local.auto.inputbytes.max
        #####job对应文件的最大值,若大于该值仍会以集群方式来运行job,默认为128MB

3、开启并行计算
    一个SQL语句可能转成很多个job,不相关的job可以并行计算。
    select t1.a,t2.a from (select count(x)a from emp)t1 ,
                        (select count(x)a from emp)t2;
    from子句中两个子查询就是不相关的。

    hive.exec.parallel
        #####是否开启并行计算
    hive.exec.parallel.thread.number
        #####一次SQL计算中允许并行执行的job个数的最大值
    

4、考虑使用严格模式
    严格模式下,用户的查询存在限制。
    查询限制:
        1、对于分区表,必须添加where对于分区字段的条件过滤;
        2、order by语句必须包含limit输出限制;
        3、限制执行笛卡尔积的查询。

    
    hive.mapred.mode
        #####是否开启严格模式,默认strict,为开启。
    
    
5、开启map端聚合
    hive.map.aggr 
        是否开启map端聚合(combiner),true为开启
    
    其他相关参数:            
        hive.map.aggr.hash.min.reduction: 
            进行聚合的最小比例,默认为0.5
            预先对十万条数据做聚合,若聚合效率值大于该值,则不聚合
        hive.map.aggr.hash.percentmemory: 
            map端聚合使用的内存的最大值
        hive.map.aggr.hash.force.flush.memory.threshold: 
            map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush
        

6、grouy by 优化
    
    hive.groupby.skewindata
        是否对GroupBy产生的数据倾斜做优化,默认为false
    hive.groupby.mapaggr.checkinterval: 
        map端group by执行聚合时处理的多少行数据(默认:100000) 

    groupby产生的数据倾斜,仅设置以上两个参数还不够,
    必须设置hive.map.aggr为true先执行一次聚合。
   
7、合并map输出小文件
    浪费资源、造成的数据倾斜    

    hive.merge.mapfiles=true
        #####是否合并map输出文件
    hive.merge.mapredfiles=true
        #####是否合并reduce输出文件
    hive.merge.size.per.task=256*1000*1000
        #####合并文件的大小


8、去重统计(慎用)
    hive和其它关系数据库一样,支持count(distinct)操作,该操作会有一个reduce task来完成,极易造成数据倾斜。
    hive.groupby.skewindat
        #####将该参数设置为true,可以解决一般的数据倾斜问题。
   

9、调整map和reduce数量

    mapred.max.split.size    #####input split的最大值,map处理文件的最大值
    mapred.min.split.size.per.node    #####每个节点上input split的最小值
    mapred.min.split.size.per.rack    #####一个机架上split的最小值

 reducer数量过多可能造成小文件过多,reducer数量过少可能造成作业运行太慢。
    mapred.reduce.tasks    #####默认值-1,表示hive会自动设置reducer的数量
    hive.exec.reducers.bytes.per.reducer    #####每个reduce任务处理的数据量,默认256MB
    hive.exec.reducers.max    #####每个任务最大的reduce数


10、启用推测式执行
    一个作业的执行时间取决于最后一个task执行情况。
    如果最后一个或几个task所在机器负载较高,这就可能会大大增加作业的运行时间,形成长尾作业。
    我们可以设定一个阈值,比如最后一个或几个task执行时间超得过已经执行时间的百分之多少的时候。
    在另一台或几台低负载机器启动最后一个或几个task,哪边先执行完则采用哪边的结果。
    
    hive.mapred.reduce.tasks.speculative.execution
        是否打开推测式执行,默认为true(打开) 

        开启推测式执行的阈值
    
    #####如果整个集群负载都特别大,这种方式就要慎重啦。
        
111、jvm复用
    MapReduce的每个task都是一个进程,进程的启用和销毁都需要大量时间。
    启用jvm复用,则下一个task直接使用上一个task占用的进程,这样可以大大地提升作业的性能。
        
    mapred.job.reuse.jvm.num.tasks
        默认值为1,表示一个JVM可以顺序执行的tsak数量为1。

    缺点:
        task插槽所占资源只有到所有的task即整个job全部执行完成时,才会释放该task插槽资源!



12、谓词下压(predicate pushdown)
    将外层查询块的WHERE子句中的谓词移入所包含的较低层查询块(例如视图)。
    从而能够提早进行数据过滤以及有可能更好地利用索引。
    
    hive.optimize.ppd    
        #####是否支持谓词下压,默认开启
    hive.optimize.ppd.storage    
        #####谓词下推开启时,谓词是否下推到存储handler,默认开启,在谓词下推关闭时不起作用
    hive.ppd.recognizetransivity
        #####在等值join条件下是否产地重复的谓词过滤器,默认开启
    
    

 

3、资源调优

4、shuffle调优

5、数据倾斜调优      

hive的优化要说起码可以说五十种,剩下的以后再记录吧,乏了。

 


   

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二百四十九先森

你的打赏是我努力的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值