
MySQL Hash Join前世今生
1. WL#2241: Hash join (变更版本:8.0.18)
主要内容:
- 新增执行类 HashJoinIterator ,实现 hash join 算法原型 (支持on-disk hash)
- HASH JOIN 仅支持 INNER JOIN ,并对使用 hash join 做了限制:关联表连接条件必须至少包含一条等值条件(equi-join condition, 如
t1.a = t2.a
),且join条件中的列不包含索引
注:这里我认为官网的
Release Notes[2]
描述是不太准确的,以如下例子为例,虽然该查询包含了非等值连接条件(non-equi-join condition, 如 t1.a <> t2.a
,t1.a = 1
, t2.a > 1
- (尽量)使用HASH JOIN算法替换BNL(Blocked Nested-Loop)连接算法
2. WL#13377: Add support for hash outer, anti and semi join( 变更版本:8.0.20)
主要内容:
- HASH INNER JOIN改进
INNER JOIN中的non-equi-join conditions
, 会被附为hash join的过滤条件:
- HAH JOIN支持outer join/anti join/semi join
- 所有使用BNL的连接,都将被转为使用HASH JOIN
- non-equi-join conditions 处理
Hash join iterator引入"extra" condition
的概念,部分non-equi-join conditions
会被当成Hash join iterator
的extra condition
, 在建hash table时,join key的计算不依赖这些条件,但会在hash查找到匹配项后,作为附加的过滤条件:
相关源码:
3. WL#13459: Optimize hash table in hash join (变更版本:8.0.23)
主要内容:
- 优化hash join table的创建方法
这里MySQL所说的“优化”, 实际上会更激进一点,这个版本中,MySQL直接使用了一个基于
robin hood hashing[3]
实现的 -
开源hash table[4]
- ,更换了原先的hash join table实现( frommem_root_unordered_multimaptorobin_hood::unordered_flat_map)
- 优化内存管理和使用,降低了 on-disk hash 的频率,提高了内存有效使用率等(其他的改进内容及提升的效果可以参考MySQL 8.0.23的
release notes[5]
以及 -
worklog #13459[6]
- 的Low Level Design页面)
本篇我们对MySQL hash join的3个重要变更做了简要的总结,算是对它的前世今生有了印象,谢谢各位阅读;之后让我们会结合具体的sql查询样例,去跟踪一下对应的代码执行流程,不日更新,敬请期待。
参考文档
[1] MySQL worklog: https://dev.mysql.com/worklog/
[2] MySQL 8.0.18 release notes#optimizer: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-18.html#mysqld-8-0-18-optimizer
[3] robin hood hashing 算法介绍: https://programming.guide/robin-hood-hashing.html
[4] robin hood hasing 开源实现: https://github.com/martinus/robin-hood-hashing
[5] MySQL 8.0.23 release notes#optimizer: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-23.html#mysqld-8-0-23-optimizer
[6] MySQL worklog #13459: https://dev.mysql.com/worklog/task/?id=13459
文章转载自公众号:GreatSQL社区
