MySQL 8.0 Hash Join如何支持无连接条件及非等值连接?
MySQL Hash Join在无连接条件场景下的实现机制解析
MySQL 8.0的Hash Join优化支持两类特殊场景:笛卡尔积和内非等值连接。
比如下面这个笛卡尔积查询(仅通过WHERE子句过滤单表数据):
mysql> EXPLAIN FORMAT=TREE -> SELECT * -> FROM t1 -> JOIN t2 -> WHERE t1.c2 > 50\G *************************** 1. row *************************** EXPLAIN: -> Inner hash join (no condition) (cost=0.70 rows=1) -> Table scan on t2 (cost=0.35 rows=1) -> Hash -> Filter: (t1.c2 > 50) (cost=0.35 rows=1) -> Table scan on t1 (cost=0.35 rows=1)
再看一个非等值连接的例子,查询SELECT * FROM t1 JOIN t2 ON t1.col1 < t2.col1;,执行计划显示先做无连接条件的Hash Join,再用连接条件做过滤:
-> Filter: (t1.col1 < t2.col1) (cost=0.70 rows=1) -> Inner hash join (no condition) (cost=0.70 rows=1) -> Table scan on t2 (cost=0.35 rows=1) -> Hash -> Table scan on t1 (cost=0.35 rows=1)
很多人会疑惑:执行计划里的(no condition)是什么意思?这种场景下Hash Join好像没起到加速作用,它的实现机制到底是怎样的?
核心实现逻辑
- 哈希表仍会构建:即使没有等值连接条件,MySQL依然会选择其中一张表(通常是小表)构建内存哈希表。这里的“无条件”只是指没有用于哈希匹配的等值键,并非不构建哈希表。
- 全量匹配+后置过滤:构建好哈希表后,遍历另一张表的每一行,将其与哈希表中的所有行进行组合(本质就是生成笛卡尔积),之后再应用WHERE或ON子句中的过滤条件(比如
t1.col1 < t2.col1)。 - 效率优势:相比嵌套循环连接,Hash Join在内存中处理哈希表的组合操作,能减少磁盘I/O的交互次数,尤其是在两张表数据量较小时,内存哈希的访问效率要高于磁盘上的循环匹配。
关于“未构建哈希表”的误解
之前有文档提到类似“未构建哈希表”的说法,实际是对执行逻辑的误读——MySQL在这类场景下依然会构建哈希表,只是匹配过程没有利用哈希键的快速查找特性,而是做全表遍历匹配,最终通过后置过滤得到结果。
内容的提问来源于stack exchange,提问作者Jacky Wang
相关产品推荐
相关产品推荐

