分桶表:join 优化与抽样
分桶表按哈希把数据切成固定数量的文件,同一个键总是落到同一个桶里。由此带来两个好处:两表分桶键与桶数一致时可以做桶对桶 join,省掉大量 shuffle;桶表也支持按桶高效抽样。代价是桶数属于表属性,写入端必须开启分桶,改桶数则是结构性变更,下游依赖桶 join 的任务都要跟着调整。
基本信息
| 核心机制 | 同键同桶 |
|---|---|
| 主要收益 | 桶 join 减少 shuffle、按桶抽样 |
| 写入要求 | 开启分桶模式,按桶数并行写入 |
| 桶数 | 与数据量匹配 |
| 变更性质 | 改桶数属于结构性变更 |
典型使用场景
- 大表 join 大表:两表按同一键分桶后可做桶 join,显著降低 shuffle 数据量
- 抽样探查:按桶抽样比随机取行更稳定,便于快速了解数据分布
- 与分区叠加:按日分区加按主键分桶,两种裁剪方式同时生效
- 桶数规划:按单桶目标数据量估算,避免桶过大或桶过多
- 变更评估:调整桶数前先列出依赖桶 join 的下游任务清单
分桶表定义与使用
分桶表定义与使用
-- 写入端开启分桶,保证数据按桶数分布
set hive.enforce.bucketing=true;
CREATE TABLE dwd_trade_order_bucket (
order_id STRING,
customer_sk BIGINT,
pay_amt DECIMAL(18,2)
)
CLUSTERED BY (customer_sk) INTO 32 BUCKETS
STORED AS ORC;
-- 按桶抽样探查数据
SELECT * FROM dwd_trade_order_bucket TABLESAMPLE (BUCKET 1 OUT OF 32);分桶设计与影响
| 项目 | 要求 | 不满足的后果 |
|---|---|---|
| 分桶键 | 与 join 键一致 | 退化为普通 shuffle join |
| 桶数 | 两表相同或成倍数关系 | 桶 join 无法使用 |
| 写入模式 | 开启分桶 | 数据分布与桶定义不一致 |
| 抽样 | 按桶取样 | 行级抽样结果不稳定 |
分桶与分区可以叠加:分区裁剪减少扫描量,分桶减少 join 的 shuffle,两者解决的问题不同,不能互相替代。
桶数调整会同时影响写入并行度与下游 join 计划,需要按改表结构的流程走评审与通知,而不是顺手改个数字。
写入数据的分布决定分桶键是否合适:如果某个键的取值高度集中(例如大量订单属于同一个大客户),分桶会明显倾斜,单桶过大,分桶收益随之消失。