Hive调优

lix_uan
• 阅读 827

Explain查看执行计划

  • 在查询语句前加explain

    explain select * from table;
    
    # 查看详细执行计划
    explain extended select * from table;

建表优化

分区表

# 创建分区表
create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (day string)
row format delimited fields terminated by '\t';

# 加载数据到分区表中
load data local inpath '/opt/module/data/dept_20220221.log' into table dept_partition partition(day='20220221');

# 单分区查询数据
select * from dept_partition where day='20220221';

# 多分区联合查询
select * from dept_partition where day='20200401'
union
select * from dept_partition where day='20200402'

# 增加单个分区
alter table dept_partition add partition(day='20220404');

# 同时删除多个分区
alter table dept_partition drop partition (day='20220404'), partition(day='20220405');

# 查看分区表有多少分区
show partitions dept_partition;

# 查看分区表结构
desc formatted dept_partition;

二级分区

# 创建二级分区表
create table dept_partition2(
    deptno int, 
    dname string, 
    loc string)
    partitioned by (day string, hour string)
    row format delimited fields terminated by '\t';

# 正常加载数据
load data local inpath '/opt/module/data/dept_20220401.log' into table
dept_partition2 partition(day='20220401', hour='12');

# 查询分区数据
select * from dept_partition2 where day='20200401' and hour='12';

动态分区

# 开启动态分区功能,默认true
set hive.exec.dynamic.partition=true;

# 设置为非严格模式,默认为严格模式,必须指定至少一个静态分区
set hive.exec.dynamic.partition.mode=nonstrict;

# 所有MR节点最大可以创建的动态分区数
set hive.exec.max.dynamic.partitions=1000;

# 每个MR节点上最大可用创建的动态分区数,根据实际情况定
set hive.exec.max.dynamic.partitions.pernode=365

# 整个MRJob中,最大可以创建的HDFS文件数
set hive.exec.max.created.files=100000

分桶表

  • 分区针对的是数据的存储路径,分桶针对的是数据文件
  • 注意事项
    • reduce个数设置为-1,让Job自行决定需要用多少个reduce
    • 从hdfs中load数据到分桶表中,避免本地文件找不到
    • 不要使用本地模式
# 创建分桶表
create table stu_buck(id int, name string)
clustered by(id) 
into 4 buckets
row format delimited fields terminated by '\t';

# 查看表结构
desc formatted stu_buck;

# load方式导入数据到分桶表中
load data inpath  '/student.txt' into table stu_buck;

# 查询分桶的数据
select * from stu_buck;

抽样查询

select * from stu_buck tablesample(bucket 1 out of 4 on id);

HQL语法优化

group by

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

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

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

Vectorization

# 批处理,比单条记录单次获得效率更高
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;

多重模式

insert int t_ptn partition(city=A). select id,name,sex, age from student where city= A;
insert int t_ptn partition(city=B). select id,name,sex, age from student where city= B;

# 一次读取,多次插入,修改为:
from student
insert int t_ptn partition(city=A) select id,name,sex, age where city= A
insert int t_ptn partition(city=B) select id,name,sex, age where city= B

in/exists语句

select a.id, a.name from a where a.id in (select b.id from b);
select a.id, a.name from a where exists (select id from b where a.id = b.id);

# 可以使用Join来改写
select a.id, a.name from a join b on a.id = b.id;

# 应该转换成 left semi join
select a.id, a.name from a left semi join b on a.id = b.id;

CBO优化(成本优化器)

# join的时候,前面的表会被加载到内存中,后面的表进行磁盘扫描
# 开启CBO,以最小的代价执行最好的代价
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;

谓词下推

# 谓词下推,默认是true
set hive.optimize.ppd = true; 

MapJoin

# 设置自动选择MapJoin,默认为true
set hive.auto.convert.join=true;

# 大表小表的阈值设置(默认25M以下认为是小表)
set hive.mapjoin.smalltable.filesize=25000000;

大表SMB Join

# 设置参数
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
# 创建分桶表一
create table bigtable_buck1(
    id bigint,
    t bigint,
    uid string,
    keyword string,
    url_rank int,
    click_num int,
    click_url string)
clustered by(id)
sorted by(id)
into 6 buckets
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/data/bigtable' into table bigtable_buck1;

# 创建分桶表二,分桶数和第一张表的分桶数成倍数关系
create table bigtable_buck2(
    id bigint,
    t bigint,
    uid string,
    keyword string,
    url_rank int,
    click_num int,
    click_url string)
clustered by(id)
sorted by(id)
into 6 buckets
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/data/bigtable' into table bigtable_buck2;

# 测试
insert overwrite table jointable
select b.id, b.t, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from bigtable_buck1 s
join bigtable_buck2 b
on b.id = s.id;

数据倾斜

单表数据倾斜

  • 使用参数

    # 是否在Map端进行聚合,默认为True
    set hive.map.aggr = true;
    # 在Map端进行聚合操作的条目数目
    set hive.groupby.mapaggr.checkinterval = 100000;
    # 有数据倾斜的时候进行负载均衡(默认是false)
    set hive.groupby.skewindata = true;
  • 增加Reduce数量(多个key同时导致数据倾斜)

    # 每个Reduce处理的数据量默认是256MB
    set hive.exec.reducers.bytes.per.reducer = 256000000
    # 每个任务最大的reduce数,默认为1009
    set hive.exec.reducers.max = 1009

Join数据倾斜

# join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.skewjoin.key=100000;
# 如果是join过程出现倾斜应该设置为true
set hive.optimize.skewjoin=false;

Job优化

Hive Map优化

  • 增加map数

    # 设置最大切片值为100个字节
    set mapreduce.input.fileinputformat.split.maxsize=100;
  • 小文件合并

    # 在map-only任务结束时合并小文件,默认true
    set hive.merge.mapfiles = true;
    # 在map-reduce任务结束时合并小文件,默认false
    set hive.merge.mapredfiles = true;
    # 合并文件的大小,默认256M
    set hive.merge.size.per.task = 268435456;
    # 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
    set hive.merge.smallfiles.avgsize = 16777216;
  • Map端聚合

    # 相当于map端执行combiner
    set hive.map.aggr=true;
  • 推测执行

    # 为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果
    set mapred.map.tasks.speculative.execution = true

Hive Reduce优化

  • 合理设置Reduce数

    # 每个Reduce处理的数据量默认是256MB
    set hive.exec.reducers.bytes.per.reducer = 256000000
    # 每个任务最大的reduce数,默认为1009
    set hive.exec.reducers.max = 1009
  • reduce个数并不是越多越好

    • 启动和初始化reduce会消耗时间和资源
    • 有多少个reduce,就会有多少个输出文件,容易造成小文件过多

任务整体优化

  • Fetch抓取

    <property>
        <name>hive.fetch.task.conversion</name>
        <value>more</value>
    </property>
  • 本地模式

    # 开启本地模式
    set hive.exec.mode.local.auto=true; 
    # 设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M
    set hive.exec.mode.local.auto.inputbytes.max=50000000;
    # 设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
    set hive.exec.mode.local.auto.input.files.max=10;
  • 并行执行(数据量很大,sql很长的时候使用)

    # 打开任务并行执行,默认为false
    set hive.exec.parallel=true; 
    # 同一个sql允许最大并行度,默认为8
    set hive.exec.parallel.thread.number=16; 
  • JVM重用(小文件过多的时候用)

  • 严格模式

    # 分区表不使用分区过滤
    # order by没有limit过滤
    # 笛卡尔积
    hive.strict.checks.no.partition.filter=true

Hive on Spark

set hive.execution.engine=spark;
set spark.executor.memory=11.2g;
set spark.yarn.executor.memoryOverhead=2.8g;
set spark.executor.cores=4;
set spark.executor.instances=40;
set spark.dynamicAllocation.enabled=true;
set spark.serializer=org.apache.spark.serializer.KryoSerializer;
点赞
收藏
评论区
推荐文章
浅梦一笑 浅梦一笑
4个月前
初学 Python 需要安装哪些软件?超级实用,小白必看!
编程这个东西是真的奇妙。对于懂得的人来说,会觉得这个工具是多么的好用、有趣,而对于小白来说,就如同大山一样。其实这个都可以理解,大家都是这样过来的。那么接下来就说一下python相关的东西吧,并说一下我对编程的理解。本人也是小白一名,如有不对的地方,还请各位大神指出01名词解释:如果在编程方面接触的比较少,那么对于软件这一块,有几个名词一定要了解,比如开发环
光头强的博客 光头强的博客
4个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
4个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
4个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
4个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
3个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
helloworld_34035044 helloworld_34035044
7个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
NVIDIA安培架构下MIG技术分析
关键词:NVIDIA、MIG、安培一什么是MIG2020年5月,NVIDIA发布了最新的GPU架构:安培,以及基于安培架构的最新的GPU:A100。安培提供了许多新的特性,MIG是其中一项非常重要的新特性。MIG的全名是MultiInstanceGPU。NVIDIA安培架构中的MIG模式可以在A100GPU上并行运行七个作业。多实
helloworld_28799839 helloworld_28799839
4个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue
lix_uan
lix_uan
Lv1
学无止境,即刻前行
7
文章
4
粉丝
0
获赞