创建分桶表
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] --根据 给定的列进行 分桶排序 指定存入 N 个桶中
需求
-- 将bucket.txt中的数据分成4个桶进行存储
CREATE TABLE IF NOT EXISTS learn5.bucket_table(
id int,name STRING
)
CLUSTERED BY(id) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";
-- 在1.X load data local inpath 方式导入分桶数据时,并不会产生分桶效果 -- 3.X 通过load可以产生桶
--load data local inpath "/usr/local/soft/hive-1.2.1/data/id_name.txt" into table learn5.bucket_table;
INSERT INTO TABLE learn5.bucket_table values ('1','student1'),('2','student2'),('3','student3'),('4','student4'),('5','student5'),('6','student6'),('7','student7'),('8','student8');
启用桶表
set hive.enforce.bucketing=true;
--限制对桶表进行load操作 --3.x中可以使用
set hive.strict.checks.bucketing = false;
通过查看表对应HDFS上的路径 可以看到数据分为4分,这样有什么好处?
通过查看000000_0文件数据可以看到,ID列中对4取余都为0
通过查看000001_0文件数据可以看到,ID列中对4取余都为1
这样我们后面去表中取数据,如果对id进行过滤,如下SQL语句
SELECT * FROM learn2.bucket_table WHERE id in ('4','1');
那么它的执行逻辑为: 对需要查找的 id ('4','1') 进行取余,
如果余数为0那么就去000000_0文件中加载数据
如果余数为1那么就去000001_0文件中加载数据
这样就可以避免加载不必要的数据,提高执行效率
查看桶的数量
DESC FORMATTED learn2.bucket_table;
-- 输出信息中 Num Buckets: 4 参数查看具体对应的桶数
注意:
- 分桶表可以和分区表搭配使用
- 分桶表中的字段需要在表字段定义时存在,分区表一定不能存在于字段定义阶段