buckets Hive之分区(Partitions)和桶(Buckets)

编辑:
发布时间: 2020-12-25 18:19:44
分享:

hive引入partition和bucket的概念,中文翻译分别为分区和桶,这两个概念都是把数据划分成块,分区是粗粒度的划分桶是细粒度的划分,这样做为了可以让查询发生在小范围的数据上以提高效率。

首先介绍分区的概念,还是先来个例子看下如果创建分区表:[code lang=”sql”]create table logs_partition –ts timestamp line 每一行日志partitioned by — 分区列 dt 日志产生日期[/code]创建分区表需要在定义表的时候声明分区列,这个分区列是个比较有意思的东西下面来看看,向表中导入数据:[code lang=”sql”]load data local inpath ‘input/hive/partitions/file1′into table logs_partitionpartition;…….— 看下表的结构hive> desc logs_partition;OKts bigint Noneline string Nonedt string Nonecountry string None

# Partition Information# col_name data_type comment

dt string Nonecountry string NoneTime taken: 0.265 seconds, Fetched: 10 row

查看一个表的所有分区hive> show partitions logs_partition;OKdt=2001-01-01/country=GBdt=2001-01-01/country=USdt=2001-01-02/country=GBdt=2001-01-02/country=USTime taken: 0.186 seconds, Fetched: 4 row

[/code]导入完数据后看下hive数据仓库表logs_partition下的文件目录结构/user/hive/warehouse/logs_partition看到了吧分区列都成了目录了,这样查询的时候就会定位到某个目录下而大大提高了查询效率,在查看表结构的时候分区列跟其他列并无区别,看个查询语句:[code lang=”sql”]SELECT ts, dt, lineFROM logsWHERE country=’GB’;

1 2001-01-01 Log line 12 2001-01-01 Log line 24 2001-01-02 Log line 4Time taken: 36.316 seconds, Fetched: 3 row

[/code]这个查询只会查询file1, file2, file4这三个文件还有一个有趣的问题就是,查看下数据文件fieldX里面都只包含两列ts和line并不包含dt和country这两个分区列,但是从查询结果看分区列和非分区列并无差别,实际上分区列都是从数据仓库的分区目录名得来的。

接下来说说桶,桶是更为细粒度的数据范围划分,它能使一些特定的查询效率更高,比如对于具有相同的桶划分并且jion的列刚好就是在桶里的连接查询,还有就是示例数据,对于一个庞大的数据集我们经常需要拿出来一小部分作为样例,然后在样例上验证我们的查询,优化我们的程序。

下面看看如何创建带桶的表[code lang=”sql”]create table bucket_user clustered by into 4 buckets;[/code]关键字clustered声明划分桶的列和桶的个数,这里以用户的id来划分桶,划分4个桶。以下为了简便划分桶的列简称为桶列hive会计算桶列的hash值再以桶的个数取模来计算某条记录属于那个桶

向这种带桶的表里面导入数据有两种方式,一种是外部生成的数据导入到桶表,一种是利用hive来帮助你生成桶表数据由于hive在load数据的时候不能检查数据文件的格式与桶的定义是否匹配,如果不匹配在查询的时候就会报错,所以最好还是让hive来帮你生成数据,简单来说就是利用现有的表的数据导入到新定义的带有桶的表中,下面来看看:已经存在的表:[code lang=”bash”]hive> select * from users;OK0 Nat2 Joe3 Kay4 Ann

hive> set hive.enforce.bucketing=true –必须设置这个数据,hive才会按照你设置的桶的个数去生成数据[/code]

下面把user的数据导入到bucketed_users中[code language=”lang="sql”]insert overwrite table bucketed-usersselect * from users;[/code]然后见证奇迹的时刻:[code lang=”bash”]hive> dfs -ls /user/hive/warehouse/bucketed_users;-rw-r–r– 1 root supergroup 12 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000000_0-rw-r–r– 1 root supergroup 0 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000001_0-rw-r–r– 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000002_0-rw-r–r– 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000003_0

hive> dfs -cat /user/hive/warehouse/bucketed_users/000000_0;0Nat4Ann

[/code]

下面来看看利用bucket来对示例数据进行查询[code lang=”sql”]—带桶的表select * from bucketed_userstablesample;

—不带桶的表select * from userstablesample);

[/code]tablesample的作用就是让查询发生在一部分桶上而不是整个数据集上,上面就是查询4个桶里面第一个桶的数据相对与不带桶的表这无疑是效率很高的,因为同样都是需要一小部分数据,但是不带桶的表需要使用rand函数,需要在整个数据集上检索。

相关阅读
热门精选
孩子 皮肤