Hive性能优化之表设计优化1

简介: Hive性能优化之表设计优化1

1 分区表

1.1 Hive查询基本原理

Hive的设计思想是通过元数据将HDFS上的文件映射成表,基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时,默认将其转换为分布式计算MapReduce程序对

HDFS中的数据进行读取处理的过程。

例如,当我们在Hive中创建一张表tb_login并关联HDFS上的文件,用于存储所有用户的登录信

息,当我们对这张表查询数据时,Hive中的实现过程如下:

⚫ step1:创建表

--创建数据库
create database tb_part;
--创建表
create table tb_login(
userid string,
logindate string
) row format delimited fields terminated by ' '\t' ';

◼ HDFS中自动在Hive数据仓库的目录下和对应的数据库目录下,创建表的目录

⚫ step2:关联数据

load data local inpath '/export/data/login.log' into table tb_login;

◼ 数据会被自动放入HDFS中对应的表的目录下

◼ 数据在表中可以被正常读取

⚫ step3:查询数据

-- 统计3月24号的登录人数
select
logindate,
count(*) as cnt
from tb_login
where logindate = '2021- - 03- - 24'
group by logindate;

◼ 当执行查询计划时,Hive会使用表的最后一级目录作为底层处理数据的输入

◼ 先根据表名在元数据中进行查询表对应的HDFS目录

◼ 然后将整个HDFS中表的目录作为底层查询的输入,可以通过explain命令查看执行计

划依赖的数据

explain extended
select
logindate,
count ( * ) as cnt
from tb_login
where logindate = '2021- - 03- - 24'
group by logindate;

1.2 普通表结构问题

默认的普通表结构中,表的最后一级目录就是表的目录,而底层的计算会使用表的最后一级目录作为Input进行计算,这种场景下,我们就会遇到一个问题,如果表的数据很多,而我们需要被

处理的数据很少,只是其中一小部分,这样就会导致大量不必要的数据被程序加载,在程序中被过

滤,导致大量不必要的计算资源的浪费。

例如,上面的需求中,只需要对2021-03-24日的数据进行计算,但实际上由于表结构的设计,

在底层执行MapReduce时,将整张表的数据都进行了加载,MapReduce程序中必须对所有数据进

行过滤,将3月24号的数据过滤出来,再进行处理。假设每天有1G的数据增量,一年就是365GB的

数据,按照业务需求,我们每次只需要对其中一天的数据进行处理,也就是处理1GB的数据,程序

会先加载365GB的数据,然后将364GB的数据过滤掉,只保留一天的数据再进行计算,导致了大量

的磁盘和网络的IO的损耗。

1.3 分区表设计思想

针对上面的问题,Hive提供了一种特殊的表结构来解决——分区表结构。分区表结构的设计思

想是:根据查询的需求,将数据按照查询的条件【一般都以时间】进行划分分区存储,将不同分区

的数据单独使用一个HDFS目录来进行存储,当底层实现计算时,根据查询的条件,只读取对应分

区的数据作为输入,减少不必要的数据加载,提高程序的性能。

例如,上面的需求中,我们可以将每天的用户登录数据,按照登陆日期进行分区存储到Hive

表中,每一天一个分区,在HDFS的底层就可以自动实现将每天的数据存储在不同的目录中,当用

户查询某天的数据时,可以直接使用这一天的分区目录进行处理,不需要加载其他数据。

1.4 分区表测试

基于分区表的设计实现将所有用户的登录信息进行分区存储

⚫ 创建分区表:按照登陆日期分区

–创建表

create table tb_login_part(

userid string

)

partitioned by (logindate string)

row format delimited fields terminated by ’ ‘\t’ ';

row format delimited fields terminated by ’ ‘\t’ ';

⚫ 将所有登陆数据写入分区表,分区存储

–开启动态分区

set hive.exec.dynamic.partition.mode=nonstrict;

–按登录日期分区

insert into table tb_login_part partition(logindate)

select * from tb_login;

◼ HDFS中会自动在表的目录下,为每个分区创建一个分区目录

⚫ 查询2021-03-23或者2021-03-24的数据进行统计

select

logindate,

count ( * ) as cnt

from tb_login_part

where logindate = ‘2021- - 03- - 23’ or logindate = ‘2021- - 03- - 24’

group by logindate;

◼ 查询先检索元数据,元数据中记录该表为分区表并且查询过滤条件为分区字段,所以

找到该分区对应的HDFS目录

◼ 加载对应分区的目录作为计算程序的输入

⚫ 查看执行计划

◼ 如果不做分区表

explain extended

select

logindate,

count ( * ) as cnt

from tb_login

where logindate = ‘2021- - 03- - 23’ or logindate = ‘2021- - 03- - 24’

group by logindate;

◼ 如果做了分区表

explain extended

select

logindate,

count ( * ) as cnt

from tb_login_part

where logindate = ‘2021- - 03- - 23’ or logindate = ‘2021- - 03- - 24’

group by logindate;

目录
相关文章
|
3月前
|
SQL 存储 HIVE
Hive中的表是如何定义的?请解释表的结构和数据类型。
Hive中的表是如何定义的?请解释表的结构和数据类型。
34 0
|
4月前
|
SQL 消息中间件 数据处理
DataX读取Hive Orc格式表丢失数据处理记录
DataX读取Hive Orc格式表丢失数据处理记录
128 0
|
9天前
|
SQL 存储 分布式计算
【Hive】Hive优化有哪些?
【4月更文挑战第16天】【Hive】Hive优化有哪些?
|
10天前
|
SQL 数据库 HIVE
Hive【基础知识 05】常用DDL操作(数据库操作+创建表+修改表+清空删除表+其他命令)
【4月更文挑战第8天】Hive【基础知识 05】常用DDL操作(数据库操作+创建表+修改表+清空删除表+其他命令)
21 0
|
2月前
|
SQL 消息中间件 Kafka
Flink部署问题之hive表没有数据如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
3月前
|
SQL 分布式计算 关系型数据库
Sqoop数据导入到Hive表的最佳实践
Sqoop数据导入到Hive表的最佳实践
|
3月前
|
SQL 存储 分布式计算
Hive的性能优化有哪些方法?请举例说明。
Hive的性能优化有哪些方法?请举例说明。
53 0
|
4月前
|
SQL 分布式计算 Hadoop
Hive SQL 优化
Hive SQL 优化
50 1
|
4月前
|
SQL 存储 HIVE
❤️Hive的基本知识(二)Hive中的各种表❤️
❤️Hive的基本知识(二)Hive中的各种表❤️
30 0
|
4月前
|
SQL 存储 关系型数据库
Presto【实践 01】Presto查询性能优化(数据存储+SQL优化+无缝替换Hive表+注意事项)及9个实践问题分享
Presto【实践 01】Presto查询性能优化(数据存储+SQL优化+无缝替换Hive表+注意事项)及9个实践问题分享
97 0