MapJoin 是什么
MapJoin(也叫广播式关联)把参与关联的小表整体加载到每个 mapper 的内存里,在 map 阶段完成关联,从而完全省掉 shuffle 与 reduce 阶段。事实表关联维表是典型适用场景:维表只有几万行时,广播后作业耗时明显下降。开启 hive.auto.convert.join=true 之后,Hive 会依据表的统计信息自动把符合条件的 JOIN 转成 MapJoin。
基本信息
| 原理 | 小表广播到每个 mapper,本地完成关联 |
|---|---|
| 主要收益 | 免 shuffle,少一轮落盘与网络传输 |
| 自动转换开关 | hive.auto.convert.join |
| 小表阈值 | hive.auto.convert.join.noconditionaltask.size |
| 主要风险 | 小表实际过大,mapper 内存溢出 |
典型使用场景
- 事实表关联小维表:维表几万行以内,广播后 map 阶段即可完成关联
- 大表 JOIN 大表但其中一侧可过滤到很小:先过滤再广播,避免 shuffle
- JOIN 键存在热点:广播能绕开按 key 分区带来的倾斜
- 追求作业稳定性:减少 shuffle 同时减少了落盘与失败重试的代价
- 倾斜场景兜底:把热点维度的维表广播,热点 key 不再集中到单个 reducer
相关设置
| 项 | 说明 | 注意点 |
|---|---|---|
| 自动转换 | 开关打开后按统计信息自动判断 | 依赖统计信息是否准确 |
| 小表阈值 | 控制可转换为 MapJoin 的表大小 | 默认约 25MB,需按 mapper 内存调整 |
| 显式提示 | 用 MAPJOIN 提示强制指定广播表 | 别名写错则提示静默失效 |
| 内存风险 | 广播表常驻每个 mapper 内存 | 大表被误判为小表会导致内存溢出 |
MapJoin 写法
MapJoin 写法
set hive.auto.convert.join=true; -- 开启自动转换
set hive.auto.convert.join.noconditionaltask.size=26214400; -- 约 25MB,按 mapper 内存调整
-- 显式提示:把小维表 d 广播到每个 mapper
SELECT /*+ MAPJOIN(d) */ o.order_id, d.customer_name
FROM dwd_trade_order_di o
JOIN dim_customer d ON o.customer_sk = d.customer_sk
WHERE o.dt='2026-10-13';所谓「小表」实际不小会导致 mapper 内存溢出:表的统计信息过期时优化器会误判,需要定期更新统计信息,或者改用显式提示并人工确认表大小。
统计信息是自动转换的前提:长期不收集统计信息的表,优化器看到的行数可能只有几千行,实际却有上亿行,判断必然失准。定期收集统计信息比事后反复调参有效。