Hive相关优化

1.行存储和列存储

在这里插入图片描述

  • 列存储:每个文件存储一个列,多个文件存储多个列,多个文件合成一张二维表
    优点:
  1. 针对列的增删改查都很容易
  2. 列单独存储,对于每个列都可以进行单独排序,性能更好
  3. 列单独存储,可以针对每个列的数据类型设置针对性的压缩算法
  4. 可以指定列加载到内存中,更加节省内存

缺点:对于整行的操作性能很低,同时对事务的支持性不行

  • 行存储:数据行存储,一个文件表达二维表
    优点:
  1. 概念简单容易理解,日常生活中用到的都是行存储,例如CSV和Txt文件
  2. 针对行操作更快捷
  3. 事务性操作比较好

缺点:

  1. 针对列的操作性比较低,无论操作哪个列都要取出一整行的数据
  2. 不能针对列的数据类型设置压缩算法,压缩率不高(相对于列存储)
  3. 只能针对某一列进行排序,不能针对每个列进行排序
  4. 扩展列、删除列不方便

2.Hive分区

  1. 静态分区
    insert into … partition(year=‘2020’, month=‘09’)
  2. 动态分区
insert into ...... partition(year, month)
开启动态分区,同时要求非严格模式
set hive.exec.dynamic.partition=true; 是开启动态分区
set hive.exec.dynamic.partition.mode=nonstrict; 
这个属性默认值是strict,就是要求分区字段必须有一个是静态的分区值,当前设置为nonstrict,那么可以全部动态分区
  1. 混合分区
这种方式要求静态在前:
insert into ......partition(year='2020', month)
  1. 相关设置参数
    在这里插入图片描述

3.Hive分桶优化

  1. 概念:分桶和分区不同,分区是粗粒度的划分数据,并且是大范围的,分区划分的是文件夹,分桶划分的是文件

分区机制:分区就是通过文件夹的方式大范围切分表数据
分桶机制:分桶就是通过文件的方式在细粒度上切分表数据

  1. 什么时候用分桶?
1.查询性能优化(在有join的场景下)
如果分区数量过多,会对文件系统造成负载压力。
分桶是hash散列,如果分桶key相同,一定在一个文件内。当进行JOIN的时候,分桶就可以帮助完成文件与文件的对应。提升JOIN的性能

2.数据采样
我们用的都是大数据系,特点是数据量够大。
大量的数据如果做验证,比较消耗性能。
如果能够抽取一部分数据做验证,分桶就比较适合做数据采样用。
  1. 分桶表的数据写入
    分桶表,不能够用load data的形式加载,也就是说只能够INSERT 来执行数据插入。
    也就是,分桶表不能够直接用sqoop导入数据

sqoop导入方案:创建一个不带分桶的临时表,用sqoop将数据导入临时表。
再执行:INSERT INTO 正式表 SELECT * FROM 临时表;

4.MapJoin优化

  1. MapJoin优化:将Join发生在Map端,而不再Reduce端
  2. 如果在map端Join,每一个map都要有对应的数据存在内存中,也就是:
  • 主表数据分散在各个map中
  • 被关联的表,肯定要全量的存在各个map的内存中
  1. 场景限制
    一般用于大表Join小表的场景
  2. 参数
# 开启自动执行MapJoin(达到条件,会自动走Map的Join而不是Reduce的Join)
set hive.auto.convert.join=true;
# 使用MapJoin的阈值设置,默认是20MB
set hive.auto.convert.join.noconditionaltask.size=512000000
/* 这个设置表示,如果N张表执行Join,N - 1张表的大小小于这个阈值,即可走MapJoin */
  1. 显式的告知Hive走MapJoin
在查询中加入:`/*+mapjoin()*/`
示例:
select /*+mapjoin(A)*/ f.a,f.b from A t join B f  on ( f.a=t.a and f.ftime=20110802) ;

5.Bucket-MapJoin(桶表的MapJoin)

  1. 桶MapJoin
    在大表和大表的场景下,无法使用MapJoin(因为大表指的就是超过了MapJoin允许的大小阈值)
  2. 解决:使用Bucket-MapJoin来进行优化
  3. Bucket-MapJoin优化过程:表整体无法在Map中hold住,可以将表的分桶在Map中hold住,相同于两个表的分桶和分桶之间,做局部的局部的MapJoin
  4. 限制条件
  • 必须有分桶
  • bucket数是另一个表bucket数的整数倍
    也就是可以一个桶对一个桶,或者一个桶对两个桶等。
    但不能出现一个桶对1.3个桶
  • 分桶列也是JOIN列
  1. 参数
# 开启bucket mapjoin的优化
set hive.optimize.bucketmapjoin = true;

6.SMB Join(Sorted Merge Bucket Join)优化

MapJoin优化了整表的Join流程(整表在Map内存中Join)
BucketMapJoin优化了表的局部Join(桶文件和桶文件之间在Map端的内存中Join)

SMB Join优化的是,在Shuffle过程中的性能提升(将每个桶中的数据按某一列排序)

由MapReduce的执行流程可以知道:Map和Reduce之间有Shuffle,Shuffle是需要消耗一定的时间

如果提供的数据就死已排好序的,Shuffle就可以被加速

SMB的核心:在BucketMapJoin的基础上,对桶文件进行排序

通俗一点来说就是:分桶+排序

参数

# 开启排序
set hive.enforce.sorting = true;
# 开启SMB优化的自动尝试
set hive.optimize.bucketmapjoin.sortedmerge = true;

总结:
在这里插入图片描述
参数总结:

# 开启自动执行MapJoin(达到条件,会自动走Map的Join而不是Reduce的Join)
set hive.auto.convert.join=true;
# 使用MapJoin的阈值设置,默认是20MB
set hive.auto.convert.join.noconditionaltask.size=512000000
# 开启bucket mapjoin的优化
set hive.optimize.bucketmapjoin = true;
# 开启排序
set hive.enforce.sorting = true;
# 开启SMB优化的自动尝试
set hive.optimize.bucketmapjoin.sortedmerge = true;

7.Hive索引

  1. 索引:本质上就是将数据查询的检索次数需要加载的数据量进行优化的一种手段
    大白话:加速查询的过程

  2. 优点:就是查的超快

  3. 缺点:增、删、改就是性能拖累
    对于数据库表而言,支队频繁使用过滤条件或者关联条件的列加索引最好,不要全都加

  4. 从时间复杂度和空间复杂度去分析索引:
    索引是以时间+空间换时间的操作

  • 前面的时间指的是,插入、更新、删除等操作变慢
  • 后面的时间指的是,查询的速度变快
  • 空间指的是:额外的存储来记录索引信息
  1. Hive索引类型
  • Hive原始索引(3.0废弃)
    不会自动跟随数据更新而更新,每次更细数据都需要
  • Row Group Index(行组索引)
  • Bloom Filter Index(布隆过滤器索引)
    行组索引和布隆过滤器索引,都需要使用ORC

行组索引

概念:针对某个列,行组索引是在ORC文件的每一个分块上,构建分块中针对某个列的最大值和最小值记录,通过这个记录,来确保索引数据,查询数据的时候可以pass掉大部分数据。

在这里插入图片描述
条件:

  1. Hive的表存储是ORC
  2. 创建表的时候指定TABLEPROPERTIES中有:orc.create.index = true
  3. 数据插入的时候是有序插入
  4. 主要应用数值类型的列,用于:> >= < <= !=的判断

如何使用:
创建表:

CREATE TABLE xxx stored AS ORC
TABLEPROPERTIES(
	-- 开启压缩
	'orc.compress' = 'SNAPPY',
	-- 开启行组索引
	'orc.create.index = true'
);

插入数据:

INSERT INTO TABLE xxx SELECT ......
DISTRIBUTE BY id SORT BY id;

查询数据:

set hive.optimize.index.filter=true; -- 自动使用索引优化
SELECT * FROM xxx WHERE id < 100;

布隆过滤器

对ORC中每个分块的数据,做分块索引
确保=的查询是很快的。

如果确定了分块,那么`=`判断很快。

如果不确定分块,需要挨个判断。

最好和行组索引一起使用,行组可以加速对分块的判断。

布隆索引可以加速对分块内数据的`=`判断

条件:

  1. 必须是ORC存储
  2. 创建表的时候指定TABLEPROPERTIES中有:orc.bloom.filter.columns = '字段列表逗号分隔'
  3. 只用于=判断

如何使用:布隆过滤器索引可以和行组过滤器索引一起使用,效果更好。

建表:

CREATE TABLE xxx stored AS ORC
TABLEPROPERTIES(
	-- 开启压缩
	'orc.compress' = 'SNAPPY',
	-- 开启行组索引
	'orc.create.index = true',
    -- 开启布隆过滤器
    "orc.bloom.filter.columns" = "id,price"
);

插入数据:

无要求(针对布隆过滤器)

如果使用了行组,请有序写入

查询数据:

set hive.optimize.index.filter=true; -- 自动使用索引优化
SELECT * FROM xxx WHERE id = 1000;

索引使用的限制:不要乱加索引,有消耗

使用环境:

  1. 作为关联条件的可以用索引
  2. 经常被WHERE的可以选择行组过滤索引
  3. 经常被=的,可以选择布隆过滤器
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大数据老人家i

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值