Map Join 优化
简介
Map Join 是 Lakehouse 中一种高效的 JOIN 优化方式,特别适用于小表与大表的 JOIN 场景。Map Join 将小表广播到各个计算节点,直接在 Map 阶段完成 JOIN,避免了昂贵的 Shuffle 和 Reduce 过程,从而节省资源、提高查询性能。
语法
在查询语句中添加
/*+ MAPJOIN(table_alias) */
/*+ MAPJOIN(table_alias) */
提示,其中
table_alias
table_alias
是需要广播到内存的小表别名:
SELECT /*+ MAPJOIN(small_table_alias) */
col1, col2, ...
FROM large_table large_alias
JOIN small_table small_table_alias
ON large_alias.key = small_table_alias.key;
优点
- 省去 Shuffle 阶段,减少网络传输和磁盘 I/O 开销。
- 避免数据倾斜问题,因为不需要按 JOIN 列分发数据。
- 显著提升小表 JOIN 大表场景的查询速度。
注意事项
- 小表必须能完全加载到内存,否则可能导致内存溢出。目前 Lakehouse 限制小表大小为 1 GB。
- 仅适用于小表与大表的 JOIN,不适合大表与大表的场景。
使用示例
示例 1:员工与部门关联查询
departments
departments
表(3 行)是小表,
employees
employees
表(5 行)是大表。将
departments
departments
广播到各节点完成 JOIN。
SELECT /*+ MAPJOIN(d) */
e.id,
e.name,
e.salary,
d.dept_name,
d.manager
FROM doc_test.employees e
JOIN doc_test.departments d
ON e.dept = d.dept_name;
执行结果:
+----+-------+----------+-------------+---------+
| id | name | salary | dept_name | manager |
+----+-------+----------+-------------+---------+
| 1 | Alice | 12000.00 | Engineering | Charlie |
| 2 | Bob | 9500.00 | Engineering | Charlie |
| 3 | Carol | 8500.00 | Marketing | Diana |
| 4 | Dave | 6500.00 | Marketing | Diana |
| 5 | Eve | 6000.00 | HR | Frank |
+----+-------+----------+-------------+---------+
示例 2:订单与产品关联查询
products
products
表(5 行)是小表,
orders
orders
表是大表。
SELECT /*+ MAPJOIN(p) */
o.order_id,
o.customer_id,
o.amount,
p.name AS product_name,
p.price AS unit_price,
p.category
FROM doc_test.orders o
JOIN doc_test.products p
ON o.product = p.name;
示例 3:多表 JOIN 中指定多个广播表
可以在同一个提示中指定多个小表:
SELECT /*+ MAPJOIN(d, p) */
e.name,
d.dept_name,
p.name AS product_name
FROM doc_test.employees e
JOIN doc_test.departments d ON e.dept = d.dept_name
JOIN doc_test.products p ON p.category = 'Electronics';
注意事项
MAPJOIN
MAPJOIN
提示中的表名是查询中的别名,不是原始表名。
- 如果小表超过 1 GB,Lakehouse 会忽略该提示并自动回退到普通 JOIN。
- Map Join 不支持 FULL OUTER JOIN 和 RIGHT OUTER JOIN(小表必须在右侧)。
- 在 Lakehouse 中,优化器也会根据统计信息自动选择 Map Join,无需每次手动添加提示。