Hive3:表性能优化-分区与分桶

发布于:2024-08-15 ⋅ 阅读:(136) ⋅ 点赞:(0)

一、分区

1、概念

我们知道,一个Hive表,对应的HDFS是一个文件夹。
那么,当数据非常多的时候,存放在一个文件夹中,后期进行查询操作会影响性能。
所以,Hive引入了分区管理的方式。

本质就是,在HDFS中根据分区字段,建立子层级文件夹
每个层级中,一个分区值,对应一个文件夹。
一般,我们用日期做分区字段。
分区字段可以是一个,也可是多个。
对应就是单层级和多层级目录。

可以简单的理解为,将一个大数据量的表,分成多个目录进行存储管理。
类似于MySQL的索引作用。

单层级
按月分区
在这里插入图片描述
多层级
按月,日两个层级分区
在这里插入图片描述

2、实操

2.1、基本语法

CREATE TABLE myhive.score(...) PARTITIONED BY (分区列 列类型, ......) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '';

2.2、创建单分区表

刚创建分区表的时候,表目录score内部是没有分区目录的,因为没有数据。

CREATE TABLE myhive.score(id string,cid string,score int)
PARTITIONED BY (month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

2.3、加载数据到对应分区

可以看出,分区列也算是表的一个字段,但是,数据来源不同

LOAD DATA INPATH '/tmp/score.txt' INTO TABLE myhive.score partition (month = '202408');
LOAD DATA INPATH '/tmp/score.txt' INTO TABLE myhive.score partition (month = '202409');

在这里插入图片描述

2.4、HDFS目录

不同分区值的数据,在不同的目录中,单都属于一个层级的目录。
在这里插入图片描述

2.5、创建多分区表

CREATE TABLE myhive.score2(id string,cid string,score int)
    PARTITIONED BY (year string,month string,day string)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

2.6、加载数据到指定分区

注意:加载数据是,分区列必须对应赋值,少了或多了都会报错。

LOAD DATA LOCAL  INPATH '/home/atguigu/score.txt' INTO TABLE myhive.score2
    partition (year='2024',month='08',day='01');

在这里插入图片描述

2.7、HDFS目录

在这里插入图片描述

二、分桶

1、概念

分桶和分区一样,也是一种通过改变表的存储模式,从而完成对表优化的一种调优方式
但和分区不同,分区是分目录存储数据,分桶是分文件存储数据
Hive的分桶,对应的Hadoop中MapReduce程序的分区逻辑。关系到Reduce Task的线程数量
几个分桶,对应几个文件
在这里插入图片描述

2、实操

2.1、基本语法

开启分桶的自动优化(自动匹配reduce task数量和桶数量一致)

SET HIVE.ENFORCE.BUCKETING=true;

创建课程表

CREATE TABLE course (c_id string,c_name string,t_id string)
CLUSTERED BY(c_id) INTO 3 BUCKETS 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

2.2、加载数据

注意,分桶表加在数据,无法用load data方式。因为这个方式不走MapReduce程序。
只能用insert select方式。

  1. 创建一个临时表(外部表或内部表均可),通过load data加载数据进入表
  2. 然后通过insert select 从临时表向桶表插入数据
--向分桶表加载数据
--1、先创建一个临时表
create table course_temp (c_id string,c_name string,t_id string)
    row format delimited fields terminated by '\t';
--2、向临时表中load data数据
LOAD DATA LOCAL  INPATH '/home/atguigu/course.txt' INTO TABLE myhive.course_temp;
--3、把临时表的数据insert select到分桶表中
insert overwrite table myhive.course select * from myhive.course_temp cluster by (c_id);

2.3、分桶的底层逻辑

如上案例
创建了一个3 bucket的分桶表
所以,数据会分成三份存储
那么,划分逻辑是什么呢?

数据的三份划分基于分桶列的值进行hash取模来决定
由于load data不会触发MapReduce,也就是没有计算过程(无法执行Hash算法),只是简单的移动数据而已,所以无法用于分桶表数据插入。

三、分桶分区综合应用

分区和分桶可以结合使用,以进一步提高查询性能和管理灵活性。通过将表进行分区和分桶,可以实现更细粒度的数据组织和查询优化。

例如,可以创建一个分区表,并在每个分区中使用分桶进行数据划分。以下是创建分区和分桶表的示例:

CREATE TABLE my_partitioned_bucketed_table (
  col1 INT,
  col2 STRING
)
PARTITIONED BY (dt STRING, country STRING)
CLUSTERED BY (col1) INTO 3 BUCKETS
SORTED BY (col2);

加载数据,需要同时指定分区和桶的编号:

INSERT OVERWRITE TABLE my_partitioned_bucketed_table PARTITION (dt='2023-01-01', country='China')
SELECT col1, col2
FROM my_table;

四、总结

1、性能提升原理分析
分区表的性能提升:在指定分区列的前提下,减少被操作的数据量,从而提升性能。
分桶表的性能提升:基于分桶列的特定操作,如:过滤、JOIN、分组,均可带来性能提升。