最近有两篇MySQL大咖级人物的文章引起了小伙伴们的关注,文章内容是关于MySQL的hash join功能。hash join看起来不够智能,于是我打算一探究竟,看看是否能发现些端倪,文末解释了大咖们的关注点。

MySQL的hash join功能是在8.0.18版本正式推出的,最初的功能仅支持inner join,其它连接类型也即将支持。(空口无凭,有图为证!)

https://dev.mysql.com/worklog/

在这里简单的介绍一下MySQL的hash join 在各种连接类型的实现方法。

inner join:

  • Classic hash join:经典的哈希连接算法分为两个阶段,构建和探测。

构建阶段:从需要进行连接的两个表中指定一个为“构建”表,该表读入内存生成哈希表,通过表的连接属性计算哈希值。例如:

SELECT * FROM t1 JOIN t2 on (t1.id = t2.id); 假设指定t1为构建表,则使用t1.id计算哈希值。

探测阶段:连接中另外的表作为探测阶段的输入使用,通过该表的连接属性计算哈希值(使用t2.id),每行数据使用其哈希值到内存中的哈希表进行查找,如果匹配记录,则输出结果。

使用经典算法要求构建表全部读入内存中,如果不能全部读入内存,将会分多次读入,会导致探测阶段产生多次读入操作。因此经典算法不是十分理想。

  • 基于磁盘的hash join:需要将构建表和探测表分割成若干个小文件保存在磁盘上,文件的大小要保证可以完全读入内存中(分割文件的算法采用与哈希表不同的哈希函数,目的是使相同哈希值的构建表和探测表的数据保存在同一文件内,并且数据的分布更加均匀)。接下来的操作和经典算法的过程差不多,每次读入一部分文件进行处理,直到所有的分割文件处理结束。

Inner non equi-join: 使用哈希连接执行该类查询,将会对两个连接表进行交叉连接,之后使用条件作为过滤。

Semijoin: 使用哈希连接执行,将会利用子查询部分作为构建表,通过连接属性计算哈希值,然后使用外部查询的连接属性的哈希值进行匹配,输出匹配的结果。

Antijoin: 与Semijoin非常相似,不同的是输出不匹配结果。

Left outer join: 左连接右侧的表为构建表。使用连接属性计算哈希值,然后使用左侧表的连接属性计算哈希值,到哈希表内进行查找,如果匹配,输出连接记录,否则输出NULL。

Right outer join: 执行方式与左连接相反。



hash join能用吗?使用效果如何?从很多人的试用反馈来看,使用hash join对比之前的查询性能大幅提高,但某些情况下会产生资源过度消耗的现象,原因在于,目前优化器还没有对hash join部分进行修改,仍旧将其视为BNL。因此出现了一些不理想的优化状态,这个问题将会在未来的工作中解决。目前可以参照叶金荣老师的文章建议。

https://mp.weixin.qq.com/s/gYledARCZHvrlnCEmh2mtw

欢迎各位小伙伴试用hash join,并反馈结果。让我们一起期待下一个版本的推出!

©著作权归作者所有:来自51CTO博客作者mb5ff97fc6948e0的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 为什么要远程连接Linux系统?linux操作系统入门
  2. 【Nest教程】连接MySQL数据库
  3. 配置文件中的数据库连接串加密了,你以为我就挖不出来吗?
  4. CentOS7配置IP和远程连接
  5. 克隆虚拟机和相互登录
  6. 聊聊TCP连接耗时的那些事儿
  7. Redis安装与使用之Java连接Redis
  8. 批量杀死MySQL连接的几种方法
  9. 使用Mosh来优化SSH连接

随机推荐

  1. linux下php安装php-kafka和php-rdkafka扩
  2. PHP脚本导出MySQL数据字典(代码示例)
  3. php求两数组交集的三种方法详解
  4. php在mysql里批量插入数据(代码实例)
  5. PHP实现页面静态化、纯静态化及伪静态化
  6. 解析PHP中的安全模式(safe_mode)
  7. php用逗号格式化数字的方法(代码示例)
  8. PHP作用域和文件夹操作示例
  9. Windows php5.6安装Imagick库的方法详解
  10. 用PHP写一个计算器(附完整代码)