Merge Join

最近更新时间:2026-06-30 16:45:31

我的收藏

什么是 Merge Join

Merge Join 又称 Sort Merge Join,是多表关联查询中一种基于排序匹配的 Join 算法。其核心步骤为:先对两张关联表按 Join 键分别排序,再从两个有序结果集中按顺序读取并匹配数据。
与 Hash Join 不同,Merge Join 依赖输入数据的有序性。当 Join 键已经天然有序(例如 Join 键为两表的主键,且查询执行计划已包含相应有序输入)时,Merge Join 无需额外排序即可直接进行归并匹配,性能优于 Hash Join;反之,如果 Join 键无序,Merge Join 需要先付出额外排序代价,整体性能通常不及 Hash Join。
列存只读分析实例在主键场景下支持 Merge Join,由优化器在条件满足时自动选择,也可通过 Hint 强制启用。

适用场景

Merge Join 适用于以下查询场景:
Join 类型为等值连接(仅支持 = 谓词,例如 A.a = B.a),不支持范围连接和 NULL-safe 等值连接(<=>)。
Join 键为两表主键或具有相同排序前缀,使输入数据天然有序,可省去额外排序步骤。
Join 双方对应列的数据类型一致(不同类型可能导致优化器无法选择 Merge Join)。
注意:
以下情况无法使用 Merge Join:
Join 列类型为 ENUMSET
Join 条件包含 <=>(NULL-safe 等值比较)。
Join 条件为非等值表达式(例如 ><BETWEEN)。

使用方法

支持通过 Hint 强制走 Merge Join,等效写法包括 merge_joinlibra_smjuse_merge,参数为参与 Join 的表名或别名列表。
示例:强制 orderslineitem 走 Merge Join
SELECT /*+ merge_join(o, l) */ *
FROM orders o, lineitem l
WHERE o.o_orderkey = l.l_orderkey;
等效写法:
SELECT /*+ libra_smj(o, l) */ * FROM orders o, lineitem l WHERE o.o_orderkey = l.l_orderkey;

SELECT /*+ use_merge(o, l) */ * FROM orders o, lineitem l WHERE o.o_orderkey = l.l_orderkey;
如需禁止特定 Join 走 Merge Join,可使用否定 Hint no_use_merge
SELECT /*+ no_use_merge(o, l) */ *
FROM orders o, lineitem l
WHERE o.o_orderkey = l.l_orderkey;

验证执行计划

通过 EXPLAIN 命令查看 Join 算子,若实际选用了 Merge Join,输出中将包含 MergeJoin_* 字样:
EXPLAIN SELECT /*+ merge_join(o, l) */ *
FROM orders o, lineitem l
WHERE o.o_orderkey = l.l_orderkey;
说明:
当 Hint 指定的 Join 方式不满足前提条件(例如 Join 键非等值、Join 键类型不兼容等)时,优化器会忽略该 Hint 并回退到 Hash Join,同时输出警告信息,可通过 SHOW WARNINGS 查看原因。