MYSQL hash join 与MYSQL 使用为什么建议从8.018后开始

2021-05-05 00:00:00 数据 版本 内存 方式 放入

MYSQL 的hash join 是从8.018引入的, 众所周知MYSQL的JOIN 的方式一直是不大友好的,nested loop join 在针对数据表join方式中,速度是一个问题。优化的手段很多,驱动表的选择,先去除参与JOIN的数据的等等都是方法。


从MYSQL 8.018 版本引入了hash join,在设计时通过两个接口, open()/init() 和 read()/next() 来进行数据的处理. 在这两个接口中, JOIN 的方式仅仅是一个规则, 通过接口的数据根据情况来选择需要走的规则.

那么走HASH JOIN 的前提是 列 等于 列 数据的形式.  


hash join 也分为三类

1 classic hash join 

2 grace hash join 

3 hybrid hash join 

 


1  classic hash join  ,使用这样的HASH 的方式首先你的驱动板要小,能放入到内存是好的,如果不能完全放入可能执行的计划会再次选择

主要的工作过程分为两步 1 建立过程通过小表装入到内存中,2在与另一个表进行比对将符合的结果装入内存,如果内存不足则会将一部分结果寄存后,在继续读入信息,知道整体扫描完毕


2  GRACE hash join 


Grace hash join 主要应用于表都比较大的情况,两张表先将涉及的JOIN equal 的chunk file 都放入到disk中,想到通过disk来进行一次缓冲,这样的处理的方法比上面要浪费一次I/O 。


3  hybrid hash join

hybird hash join 并不是独立的第三种HASH JOIN 的形式,而和他的名字一样hybrid (丰田花冠部分车型有类似的标记)意思为混动,混合的意思。

hybrid hash join 主要原理就是利用 classic  和 grace 两种hash join的特点

首先我们的承认使用 classic hash join 是理想的状态,而如果表无法放入到内存中,classic 的缺陷就显露了,处理需要逐步的推送结果,和处理运算,hybrid hash join 就采用如果是小表就直接读取到内存,大表就采用grace hash join的方式先将file chunk读取到磁盘在进行操作,将classic 和 gracehash join 的优点加以利用。


mysql  8  hash join采用了 Hybrid hash join的算法,在8.018支持了inner join 的hash ,8.020 支持了 anti , semi , outer hash join 

所以如果要享受hash join ,起步就应该是8.018以上的版本,如果可以建议采用8.020以上的版本彻底利用mysql的hash join, 但需要知道的HASH JOIN 不支持输出结果的排序。


在参数方面 join_buffer_size 的大小有助于在执行计划中,较大的join buffer 更有倾向性的使用 hash join.


但实际上在高版本的MYSQL中如果想使用hash join还是有困难的, 参加下图

已经将block_nested_loop=off  关闭,并且使用了inner join 的方式,MYSQL的版本为8.023 ,也没有走相关的HASH JOIN 的方式

调整了查询的数据量也没有走hash join


相关文章