核心要点
分区(Partition):按某列值把数据拆成不同目录/文件,查询时按谓词做分区裁剪只读相关分区
分桶(Bucket):按列做 hash 取模分到固定数量的桶文件,桶数固定、桶内有序可选
分区适合低基数、常用作过滤条件的列(如日期);高基数列分区会产生海量小文件
分桶适合高基数 join/聚合列,相同分桶的两表可做 bucket join 避免 Shuffle
标准回答
分区:目录级裁剪
分区按列值把表物理拆成多个目录(如 dt=2026-06-26)。查询带分区列过滤时引擎只扫描命中的目录,即分区裁剪,大幅减少 IO。选分区列要低基数且常作过滤条件,最典型是日期;若用高基数列(如 user_id)分区会爆出海量小目录小文件,反而拖垮元数据与读取。
分桶:哈希定位与无 Shuffle Join
分桶按指定列 hash 取模分到固定数量的桶文件,桶数在建表时确定。它把数据预先按 join/聚合 key 组织好:两张表用相同列、相同桶数分桶后做 join,相同 key 必落在对应桶,可做 bucket/SortMerge join 而无需再 Shuffle;聚合与采样也能受益。
组合设计
实践中常先按日期分区(控制扫描范围与生命周期),再在分区内按高基数 join 列分桶(控制单文件大小、加速 join),兼顾裁剪与计算效率。还需关注小文件治理:分区粒度别太细,定期合并小文件。
常见误区
⚠️ 常见踩坑
用高基数列分区是经典反模式,会产生小文件风暴。分桶数一旦确定难以平滑变更,且只有当两表桶数、桶列一致时才能享受免 Shuffle join,不一致仍会触发重分布。
追问
追问 1:为什么小文件问题严重,如何治理?
小文件会膨胀元数据、增加 Task 调度与打开文件的开销,拖慢查询。治理手段:合理设置分区粒度避免过细、定期 compaction 合并小文件、写入时控制并行度与 coalesce/repartition、湖仓表格式(Iceberg/Hudi)提供自动小文件合并能力。
追问 2:动态分区写入要注意什么?
动态分区按数据值自动建分区,若分区列基数高会瞬间产生大量分区目录与小文件,甚至 OOM。需限制动态分区数、写前对分区列做合理排序/重分区使同分区数据聚到一起,并控制每分区的写入并行度。
延伸学习
与本题相关的知识库文章、术语、工具与行业资讯。