最近有两篇MySQL大咖级人物的文章引起了小伙伴们的关注,文章内容是关于MySQL的hash join功能。hash join看起来不够智能,于是我打算一探究竟,看看是否能发现些端倪,文末解释了大咖们的关注点。
MySQL的hash join功能是在8.0.18版本正式推出的,最初的功能仅支持inner join,其它连接类型也即将支持。
在这里简单的介绍一下MySQL的hash join 在各种连接类型的实现方法。
inner join:
Classic hash join:经典的哈希连接算法分为两个阶段,构建和探测。
基于磁盘的hash join:需要将构建表和探测表分割成若干个小文件保存在磁盘上,文件的大小要保证可以完全读入内存中(分割文件的算法采用与哈希表不同的哈希函数,目的是使相同哈希值的构建表和探测表的数据保存在同一文件内,
并且数据的分布更加均匀)。接下来的操作和经典算法的过程差不多,每次读入一部分文件进行处理,直到所有的分割文件处理结束。
Inner non equi-join:使用哈希连接执行该类查询,将会对两个连接表进行交叉连接,之后使用条件作为过滤。
Semijoin:使用哈希连接执行,将会利用子查询部分作为构建表,通过连接属性计算哈希值,然后使用外部查询的连接属性的哈希值进行匹配,输出匹配的结果。
Antijoin:与Semijoin非常相似,不同的是输出不匹配结果。
Left outer join:左连接右侧的表为构建表。使用连接属性计算哈希值,然后使用左侧表的连接属性计算哈希值,到哈希表内进行查找,如果匹配,输出连接记录,否则输出NULL。
Right outer join:执行方式与左连接相反。
hash join能用吗?使用效果如何?从很多人的试用反馈来看,使用hash join对比之前的查询性能大幅提高,但某些情况下会产生资源过度消耗的现象,原因在于,目前优化器还没有对hash join部分进行修改,仍旧将其视为BNL。
因此出现了一些不理想的优化状态,这个问题将会在未来的工作中解决。目前可