MYSQL hash join 终于等到她

MYSQL hash join 终于等到她

MYSQL 的多表联合查询中,只有nest loop 的查询方式,让MYSQL 一致是被“嘲笑”的地方。MYSQL 8.018 后mysql 将拥有HASH JOIN 功能,虽然对比其他数据库来说,这并不新鲜,但对于MYSQL 算是划时代的里程碑。

原理之类的先不说,先看效果。建立两个存储过程,为C1 表和 C2表插入测试数据

delimiter //

CREATE PROCEDURE insert_c1()

BEGIN

 DECLARE i int ;

DECLARE a varchar(20) ;

DECLARE b smallint ;

set i = 1;

begin 

WHILE i<=1000000 do

 set b = FLOOR(rand()*50);

if i mod 2 = 0 then

set a = 'good';

elseif i mod 3 = 0 then

set a = 'excellent';

elseif i mod 5 = 0 then

set a  = 'ordinary';

elseif i mod 4 = 0 then

set a = 'worsen';

else

set a = 'improvement';

end if;

if b < 20 then

set b = b + 15;

end if;

INSERT into test.status(status,score) values (a,b);

set i = i + 1;

END WHILE;

end;

 END

//

两个表结构是一样的

 CREATE TABLE `t1` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `c1` varchar(20) DEFAULT NULL,

  `c2` int(11) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `idx_c1` (`c1`)

) ENGINE=InnoDB 

MYSQL hash join 终于等到她

从图中可以清晰的看到查询已经走了hash  join,那老的MYSQL DBA 可能会提出一个问题,到底这个hash join 比 nest loop 能好多少,可别和MYSQL 8 VS MYSQL 5.7一样,谁快还不一定。下面做了一个对比,可以清晰的看到在某些情况下,HASH JOIN 在没有索引的情况下,比添加了索引的NEST LOOP 的速度要快了一倍。

MYSQL hash join 终于等到她

 所以到这里,

1 hash join 的确是查询中需要的功能

2 hash join 的确在某些情况下 比 NEST LOOP 要快

在说明完这些问题后,我们的讲讲为什么

在MYSQL 中hash join的构造包含两个流程  1  build  2 probe

1建立的阶段就是将需要进行JOIN 的字段,进行一个HASH 值的计算,而到底哪个表要进行这样的计算,整体SIZE 小的表将被选中,在内存中构建这个计算好值的表

2 匹配的过程,从另外一个表中将字段的值进行计算,与内存中的值匹配的就被选中,否则就抛弃。

这样操作的好处也是显而易见的,大大缩减比对的次数

NEST LOOP  如果是  N * S  则 hash join 可以比对为N * distinct S 如果distinct S 变化的值越少,则表的查询速度越快。

当然这样还会产生另一个结果,就是我们可以在某些时候放弃JOIN 中建立索引了,如果建立了索引,则MYSQL 会倾向使用 NEST LOOP ,而不走HASH JOIN ,所以到了8.018 这个版本后,MYSQL 的查询优化,可能又要添加一条想法了。

当然如果想要这个功能,首先先查查你的数据库目前支持,或打开了这个功能没有。

MYSQL hash join 终于等到她

那hash joinj就无敌了,哪里都能用  NO NO NO  要使用它是有限制的,我们下面吧索引删除

MYSQL hash join 终于等到她

下面的查询看似和上面的差不多,但就是没有走HASH JOIN 

MYSQL hash join 终于等到她

所以需要记住三个地方是是否能使用HASH JOIN 的前提

1 没有索引

2 等值运算

3 INNER JOIN 

MYSQL hash join 终于等到她

如果有兴趣可以加个群,共同提高

MYSQL hash join 终于等到她