一、Hive分区。
是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为文件夹,
比如我们要收集某个大型网站的日志数据,一个网站每天的日志数据存在同一张表上,由于每天会生成大量的日志,导致数据表的内容巨大,在查询时进行全表扫描耗费的资源非常多。那其实这个情况下,我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。
常用的分区字段都是按照时间来区分。
#创建分区表
create table t1 (
id int comment '编号',
name string comment '姓名',
age int comment' 年龄'
)
partitioned by (pdate string)
row format delimited fields terminated by '\001'
;
常用命令:
查看分区数据:
select * from t1 where pdate='2020-01-01';
查看有哪些分区:
show partitions t1;
向分区插入数据:
insert overwrite table t1 partition(pdate='2020-01-01')
select * from xxx
使用场景:
庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区或切片的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。
数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。比如vido表,分区的依据可以是电影的种类和评级,另外,按照拍摄时间划分可能会得到更一致的结果。为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件。
Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。
Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。
为啥还要分桶?分区表是将大的表文件划分成多个小文件以利于查询,但是如果数据分布不均衡,也会影响查询效率。分桶能保证数据分布均衡
二、hive分桶
分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。
分桶表的好处:
获得更高的查询处理效率:桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
使取样(sampling)更高效:在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
#常用指令:
#创建分桶表
create table t2(
id int,
name string
)
clustered by (id) sorted by(id) into 4 buckets
;
使用场景:
1.桶表专门用于抽样查询,不是用来存储数据的表,在需要抽样查询时,在创建和使用桶表。
在使用桶表之间,必须要开启桶。
三、hive分区又分桶
可以对数据表分区之后继续分桶。
create table t1 (
id int comment '编号',
name string comment '姓名',
age int comment' 年龄'
)
partitioned by (pdate string)
clustered by(id) sorted by(id) into 4 buckets
row format delimited fields terminated by '\001'
;