Hive分区分桶

布袋罗汉
• 阅读 607

分区

分区概念

在逻辑上分区表与未分区表没有区别,在物理上分区表会将数据按照分区键的列值存储在表目录的子目录中,目录名=“分区键=键值”。其中需要注意的是分区键的值不一定要基于表的某一列(字段),它可以指定任意值,只要查询的时候指定相应的分区键来查询即可。我们可以对分区进行添加、删除、重命名、清空等操作。分为静态分区和动态分区两种,静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在 SQL 执行时才能决定。

分区案例

Hive的分区功能可以帮助用户快速的查找和定位,这里我们给出了一个应用场景,通过使用Hive分区功能创建日期和小时分区,快速查找定位对应的用户与IP地址。具体步骤如下:

步骤 1 创建一张分区表,包含两个分区dt和ht分别表示日期和小时:

CREATE TABLE partition_table001 ( name STRING, ip STRING ) PARTITIONED BY (dt STRING, ht STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

步骤 2 启用hive动态分区时,需要设置如下两个参数:

set hive.exec.dynamic.partition=true;

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

步骤 3 把partition_table001表某个日期分区下的数据(如下图所示)load到目标表partition_table002中。

Hive分区分桶

  • 如果没有目标表则创建目标表partition_table002:

CREATE TABLE IF NOT EXISTS partition_table002 LIKE partition_table001;

Hive分区分桶

  • 如果使用静态分区,必须指定分区的值,如将partition_table001表中日期分区为“20190520”、小时分区为“00”的数据加载入表partition_table002中:

INSERT OVERWRITE TABLE partition_table002 PARTITION (dt='20190520', ht='00') SELECT name, ip FROM partition_table001 WHERE dt='20190520' and ht='00';

查询一下表partition_table002中我们插入的数据,结果如下图所示:

Hive分区分桶

  • 如果希望插入每天24小时的数据,则需要执行24次上面的语句。而使用动态分区会根据select出的结果自动判断数据该load到哪个分区中去,只需要一句语句即可完成,命令及结果如下所示:

INSERT OVERWRITE TABLE partition_table002 PARTITION (dt, ht) SELECT * FROM partition_table001 WHERE dt='20190520';

Hive分区分桶

步骤 4 查看表格partition_table002下的所有分区信息使用如下命令:

SHOW PARTITIONS partition_table002;

Hive分区分桶

或者拥有admin权限的用户使用dfs –ls <表存储目录>命令如下:

dfs -ls hdfs://hacluster/user/hive/warehouse/partition_table002;

Hive分区分桶

说明:
静态分区和动态分区可以混合使用,在动静结合使用时需要注意静态分区值必须在动态分区值的前面,在select中按位置顺序出现在最后(因为静态分区提前产生,动态分区运行时产生)。如果动态分区作为父路径,则子静态分区无法提前生成,会报错为动态分区不能为静态的父路径。当静态分区是动态分区的子分区时,执行DML操作会报错。因为分区顺序决定了HDFS中目录的继承关系,这点是无法改变的。

分桶

分桶概念

对于每一个表或者分区, Hive可以进一步组织成桶,也就是说分桶是更为细粒度的数据范围划分。Hive会计算桶列的哈希值再以桶的个数取模来计算某条记录属于那个桶。把表(或者分区)组织成桶(Bucket)有两个理由:

  1. 获得更高的查询处理效率。桶为表加上了额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用Map端连接(Map-side join)高效的实现。
  2. 使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

分桶案例

步骤 1 创建一张含有桶的表格,例如创建一个含有四个桶的表格bucketed_table:

CREATE TABLE bucketed_table (id INT, name STRING) CLUSTERED BY (id) INTO 4 BUCKETS;

步骤 2 设置hive.enforce.bucketing属性为true,以便自动控制上reduce的数量从而适配bucket的个数,推荐命令如下(当然也可以手动设置参数“mapred.reduce.task”去适配bucket的个数,只是多次手动修改会比较麻烦):

set hive.enforce.bucketing = true;

步骤 3 向表里插入准备好的没有划分桶的数据,例如将没有划分桶的表users的数据插入目标表bucketed_table:

INSERT OVERWRITE TABLE bucketed_table SELECT * FROM users;

Hive分区分桶

步骤 4 查看表格bucketed_table下的所有分桶信息,需要拥有admin权限的用户使用dfs –ls <表或分区存储目录>命令如下:

dfs -ls hdfs://hacluster/user/hive/warehouse/bucketed_table;

Hive分区分桶

步骤 5 对桶中的数据进行采样,使用抽样命令TABLESAMPLE(BUCKET x OUT OF y),例如对表格bucketed_table从第一个桶开始抽取1个桶数据量的样本:

SELECT * FROM bucketed_table TABLESAMPLE(BUCKET 1 OUT OF 4 ON id);

Hive分区分桶

说明:
抽样命令TABLESAMPLE(BUCKET x OUT OF y)中,y必须是表格中分桶数的倍数或者因子。Hive根据y的大小,决定抽样的比例。x表示从哪个桶开始抽取。例如,表格的总分桶数为16,tablesample(bucket 3 out of 8),表示总共抽取(16/8=)2个bucket的数据,分别为第3个桶和第(3+8=)11个桶的数据。

本文由华为云发布
点赞
收藏
评论区
推荐文章
lix_uan lix_uan
4年前
Hive调优
Explain查看执行计划在查询语句前加explainsqlexplainselectfromtable;查看详细执行计划explainextendedselectfromtable;建表优化分区表sql创建分区表createtabledeptpartition(deptnoint,dnamest
Wesley13 Wesley13
4年前
mysql之数据分区
一:概述 通过把表分成多几区间,每个区间存储符合特定表达式的数据(即在我们创建分区表时指定每个分区存储的条件例如:PARTITIONp0VALUESLESSTHAN(100)即p0区间存储小于100的数据)。二:分区类型   即根据每个区间存储值的表达式不同,可分为如下几个类型,一般都是对数字类型或时间类型的数据进行分区。2.1 R
Stella981 Stella981
4年前
Linux系统盘扩容
\Linux系统盘扩容\了解磁盘分区情况\\blkid\查看分区情况\\fdiskl\分区表\系统挂载分区\\/etc/fstab\启动挂载分区情况\双系统下分区释放空间\在windows系统下使用分区工具,减小分区的空间
Wesley13 Wesley13
4年前
Mysql 分区表
DROPTABLEIFEXISTS\frank\_test\;CREATETABLE\frank\_test\(\id\bigint(20)NOTNULLAUTO\_INCREMENTCOMMENT'主键id',\gid\bigint(20)DEFAULT'0'COMMENT'基础表id'
Wesley13 Wesley13
4年前
ORACLE创建按日期自动分区表
原文地址:https://www.cnblogs.com/yuxiaole/p/9809294.html  oracle11g支持自动分区,不过得在创建表时就设置好分区。  如果已经存在的表需要改分区表,就需要将当前表rename后,再创建新表,然后复制数据到新表,然后删除旧表就可以了。一、为什么要分区(Partition)
Wesley13 Wesley13
4年前
Mysql 表分区分类
针对Mysql数据库,表分区类型简析。【1】表分区类型(1)Range分区:按范围分区。按列值的范围区间进行分区存储;比如:id小于10存储在一个分区;id大于10小于20存储在另外一个分区;(2)List分区:按离散值集合分区。与range分区类似,不过它是按离散值进行分区。(3)Hash分区:按hash算法结果分区。对用户定义的表达式所返
Stella981 Stella981
4年前
PostgreSQL从继承到分区(二)
二、Partitioning\_table2.1关于分区表借助表的继承特性PostgreSQL实现了分区表功能,虽然相比Oracle、MySQL的分区表来说其实现过程比较麻烦,但是这种方式同样能达到分区的效果,而且对大表的查询优化效果很明显。PostgreSQL的分区表概念与其它数
Wesley13 Wesley13
4年前
mysql中的分区表
分区表的意义:当数据量非常大时(表的容量到达GB或者是TB),如果仍然采用索引的方式来优化查询,由于索引本生的消耗以及大量的索引碎片的产生,查询的过程会导致大量的随机I/O的产生,在这种场景下除非可以很好的利用覆盖索引,否则由于在查询的过程中需要根据索引回数据表查询,会导致性能受到很大的影响,这时可以考虑通过分区表的策略来提高查询的性能。
Wesley13 Wesley13
4年前
HGDB分区表的使用与管理
目录文档用途详细信息文档用途了解HGDB分区表的简单使用详细信息1.简介数据库表分区把一个大的物理表分成若干个小的物理表,并使得这些小物理表在逻辑上可以被当成一张表来使用。一般来讲我们把上述说明中的大的物理表称为父表/主表,小的物理表称为子表/分区表。主表/父表/MasterTable 该表是创建子表的模板。它是
Wesley13 Wesley13
4年前
MySQL 分区表原理及使用详解
1\.什么是表分区?表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。2\.表分区与分表的区别分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。分表与分区的区别在于:
Wesley13 Wesley13
4年前
Mysql合并表原理
1.概述:合并表是一种早期的、简单的分区实现,和分区表相比有一些不同的限制,并且缺乏优化。分区表严格来说是一个逻辑上的概念,用户无法访问底层的各个分区,对用户来说分区是透明的。但是合并表允许用户单独访问各个子表。分区表和优化器的结合更紧密,这也是未来发展的趋势,而合并表则是一种将要被淘汰的技术,在未来的版本中可能被删除。2.原理: