1. 什么是桶表?
- 定义:桶表是 Hive 中一种用于优化查询性能的数据存储方式。它通过对指定列(分桶列)的值进行哈希(Hash)计算,然后根据哈希值将数据均匀地分配到多个文件(桶)中。
- 核心目的 :
- 优化 Join 操作:当两个表在 Join Key 上有相同的分桶时,Hive 可以执行高效的分桶连接(Bucket-to-Bucket Join),大幅减少数据 shuffle。
- 高效采样查询:可以直接查询特定的一个或几个桶,而无需扫描整个表,适用于数据分析和采样。
- 数据均匀分布:相比分区表可能出现的一个分区过大的情况,桶表能更好地将数据分散到多个文件中。
. 创建桶表
create table 表名 (
id int,
name string
)
clustered by (id) ---- 指定分桶列
into 3 buckets ----指定桶的数量
stored as orc; ------ 推荐使用高效的列式存储格式
向桶表导入数据
核心原则 :不能使用 LOAD DATA 命令直接向桶表加载数据,因为 LOAD DATA 只是移动文件,不会执行分桶逻辑。必须使用 INSERT ... SELECT 语句。
1.创建临时中转表:创建一个与源数据文件格式(如文本、CSV)匹配的普通表。
create table student_temp (
id int,
name string
)
row format delimited
fields terminated by ',';
2.加载数据到临时表
load data local inpath '/path/to/student.txt' overwrite into table student_temp;
3.设置分桶参数
set hive.enforce.bucketing = true; -- 强制 Hive 执行分桶逻辑
set mapreduce.job.reduces = 3; -- 设置 Reduce 任务数等于桶数
4.插入数据到桶表
insert overwrite table student_b
select id, name from student_temp;
查询桶表数据
普通查询:与查询普通表无异。
sql
select * from student_b where id = 1001;
-
抽样查询 :使用
tablesample子句高效查询特定桶的数据。sql
-- 查询第 2 个桶的数据 select * from student_b tablesample(bucket 2 out of 3 on id);-
注意 :如果 Hive 启用了 CBO(基于成本的优化器),
tablesample可能会报错。解决方案是临时关闭 CBO:sql
set hive.cbo.enable = false;
-
. 查看桶表的 HDFS 存储
-
桶表在 HDFS 上的存储路径可以通过
describe extended student_b;命令查看location字段获得。 -
在该路径下,会看到与桶数相等的多个数据文件(如
000000_0,000001_0,000002_0),每个文件对应一个桶。 -
使用 HDFS 命令查看: bash
运行
hdfs dfs -ls /user/hive/warehouse/your_db.db/student_b
从桶表导出数据
可以使用 insert overwrite local directory 将桶表数据导出到本地文件系统。
sql
-- 导出为逗号分隔的文本文件
insert overwrite local directory '/opt/module/hive/student_b_export'
row format delimited fields terminated by ','
select * from student_b;
- 导出的结果会是多个文件(通常与 Reduce 任务数相同),每个文件包含一部分数据。
- 如果希望合并为单个文件,可以在导出前设置
set mapreduce.job.reduces = 1;。