Mysql优化_第十三篇(HashJoin篇)

1 适用场景

纯等值查询,不能使用索引

从MYSQL 8.0.18开始,MYSQL实现了对于相等条件下的HASHJOIN,并且,join条件中无法使用任何索引,比如下面的语句:

SELECT *
FROM t1
JOIN t2
ON t1.c1=t2.c1;

等值查询,使用到索引

当然,如果有一个或者多个索引可以适用于单表谓词,hash join也可以使用到。(这句话不是很懂?原句为:A hash join can also be used when there are one or more indexes that can be used for single-table predicates.

相对于Blocked Nested Loop Algorithm,以下简称BNL,hash join性能更高,并且两者的使用场景相同,所以从8.0.20开始,BNL已经被移除。使用hash join替代之。

通常在EXPLAIN的结果里面,在Extra列,会有如下描述:

Extra: Using where; Using join buffer (hash join)

说明使用到了hash join。

多个join条件中至少包含一个等值查询(可以包含非等值)

虽然hash join适用于等值join,但是,从原则上来讲,在多个join条件中,只要有每对join条件中,至少存在一个等值,Mysql就可以使用到hash join来提升速度,比如下面的语句:

SELECT * FROM t1
JOIN t2 ON (t1.c1 = t2.c1 AND t1.c2 < t2.c2) 该语句包含非等值的join条件
JOIN t3 ON (t2.c1 = t3.c1);

EXPLAIN FORMAT=TREE的结果如下:

EXPLAIN: -> Inner hash join (t3.c1 = t1.c1)  (cost=1.05 rows=1)
-> Table scan on t3 (cost=0.35 rows=1)
-> Hash
-> Filter: (t1.c2 < t2.c2) (cost=0.70 rows=1)
-> Inner hash join (t2.c1 = t1.c1) (cost=0.70 rows=1)
-> Table scan on t2 (cost=0.35 rows=1)
-> Hash
-> Table scan on t1 (cost=0.35 rows=1)

多个join条件对中完全没有等值查询(从8.0.20开始)

在Mysql8.0.20之前,如果join条件中有任何一个条件没有包含等值,那么BNL就会被应用但是从8.0.20开始,hash join也可以应用到下面的语句

mysql> EXPLAIN FORMAT=TREE
-> SELECT * FROM t1
-> JOIN t2 ON (t1.c1 = t2.c1)
-> JOIN t3 ON (t2.c1 < t3.c1)\G 该join条件不包含等值,会作为filter来使用
*************************** 1. row ***************************
EXPLAIN: -> Filter: (t1.c1 < t3.c1) (cost=1.05 rows=1)
-> Inner hash join (no condition) (cost=1.05 rows=1)
-> Table scan on t3 (cost=0.35 rows=1)
-> Hash
-> Inner hash join (t2.c1 = t1.c1) (cost=0.70 rows=1)
-> Table scan on t2 (cost=0.35 rows=1)
-> Hash
-> Table scan on t1 (cost=0.35 rows=1)

笛卡尔积

当然,也可以适用于笛卡尔积(没有指定join条件):

mysql> EXPLAIN FORMAT=TREE
-> SELECT *
-> FROM t1
-> JOIN t2
-> WHERE t1.c2 > 50\G
*************************** 1. row ***************************
EXPLAIN: -> Inner hash join (cost=0.70 rows=1)
-> Table scan on t2 (cost=0.35 rows=1)
-> Hash
-> Filter: (t1.c2 > 50) (cost=0.35 rows=1) where条件提早过滤
-> Table scan on t1 (cost=0.35 rows=1)

普通inner join完全没有等值

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 JOIN t2 ON t1.c1 < t2.c1\G
*************************** 1. row ***************************
EXPLAIN: -> Filter: (t1.c1 < t2.c1) (cost=4.70 rows=12) //join条件变成了filter
-> Inner hash join (no condition) (cost=4.70 rows=12)
-> Table scan on t2 (cost=0.08 rows=6)
-> Hash
-> Table scan on t1 (cost=0.85 rows=6)

Semijoin(Mysql文档EXPLAIN有误,这里更正下)

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1
-> WHERE t1.c1 IN (SELECT t2.c2 FROM t2)\G
*************************** 1. row ***************************
| -> Filter: (t1.c1 < t2.c1) (cost=0.70 rows=1)
-> Inner hash join (no condition) (cost=0.70 rows=1)
-> Table scan on t2 (cost=0.35 rows=1)
-> Hash
-> Table scan on t1 (cost=0.35 rows=1)
|

Antijoin(Mysql文档EXPLAIN有误,这里更正下)

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t2
-> WHERE NOT EXISTS (SELECT * FROM t1 WHERE t1.col1 = t2.col1)\G
*************************** 1. row ***************************
| -> Hash antijoin (t1.c1 = t2.c2) (cost=0.70 rows=1)
-> Table scan on t2 (cost=0.35 rows=1)
-> Hash
-> Table scan on t1 (cost=0.35 rows=1)
|

Left outer join

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1\G
*************************** 1. row ***************************
EXPLAIN: -> Left hash join (t2.c1 = t1.c1) (cost=3.99 rows=36)
-> Table scan on t1 (cost=0.85 rows=6)
-> Hash
-> Table scan on t2 (cost=0.14 rows=6)

Right outer join(MYSQL会把所有的右外连接转换为左外连接):

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 = t2.c1\G
*************************** 1. row ***************************
EXPLAIN: -> Left hash join (t1.c1 = t2.c1) (cost=3.99 rows=36)
-> Table scan on t2 (cost=0.85 rows=6)
-> Hash
-> Table scan on t1 (cost=0.14 rows=6)

相关配置

目前可以使用 join_buffer_size 系统变量来控制hash join使用到的内存大小,如果需要使用到的内存超过了这个大小,那么就会下盘,这个时候效率就会比较低了,需要使用者进行优化。

Mysql优化_第十三篇(HashJoin篇)的更多相关文章

  1. Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解

    Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解   Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...

  2. MySQL优化/面试,看这一篇就够了

    原文链接:http://www.zhenganwen.top/articles/2018/12/25/1565048860202.html 作者:Anwen~链接:https://www.nowcod ...

  3. Mysql优化_内置profiling性能分析工具

    如果要进行SQL的调优优化和排查,第一步是先让故障重现,但是这个并不是这一分钟有问题,下一秒就OK.一般的企业一般是DBA数据库工程师从监控里找到问题.DBA会告诉我们让我们来排查问题,那么可能很多种 ...

  4. mysql的优化_第十一篇(查询计划篇)

    Mysql优化(出自官方文档) - 第十一篇(查询计划篇) 目录 Mysql优化(出自官方文档) - 第十一篇(查询计划篇) 1 EXPLAIN Output Format EXPLAIN Join ...

  5. mysql优化之索引篇

    对mysql优化是一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引.主键索引.唯一索引unique.全文索引] c: 分表技术(水平 ...

  6. Mysql优化(出自官方文档) - 第三篇

    目录 Mysql优化(出自官方文档) - 第三篇 1 Multi-Range Read Optimization(MRR) 2 Block Nested-Loop(BNL) and Batched K ...

  7. Mysql优化(出自官方文档) - 第五篇

    目录 Mysql优化(出自官方文档) - 第五篇 1 GROUP BY Optimization 2 DISTINCT Optimization 3 LIMIT Query Optimization ...

  8. Mysql优化(出自官方文档) - 第八篇(索引优化系列)

    目录 Mysql优化(出自官方文档) - 第八篇(索引优化系列) Optimization and Indexes 1 Foreign Key Optimization 2 Column Indexe ...

  9. Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇)

    目录 Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇) 1 Optimizing Data Size 2 Optimizing MySQL Data Types 3 Optimizing ...

随机推荐

  1. [MySQL数据库之事务、读现象、数据库锁机制、多版本控制MVCC、事务隔离机制]

    [MySQL数据库之事务.读现象.数据库锁机制.多版本控制MVCC.事务隔离机制] 事务 1.什么是事务: 事务(Transaction),顾名思义就是要做的或所做的事情,数据库事务指的则是作为单个逻 ...

  2. MakeCode图形编程应用在micro:bit上的多工性能实测

    1. 简述 本文不涉及对测试中所用到的设备或软件的推广. micro:bit 是一款由英国广播电视公司(BBC)为青少年编程教育设计,并由微软,三星,ARM,英国兰卡斯特大学等合作伙伴共同完成开发的微 ...

  3. 通过Cloudflare开启全站https

    Cloudflare 添加域名后,会自动生成通用证书,快速开启全站HTTPS,服务端不用做任何修改,还可以选择多种开启模式 一.注册Cloudflare账号 直接打开网站:https://www.cl ...

  4. jQuery的入口和jQurey的对象切换

    jQuery jQuery的导入 通过script标签的src属性,link标签是导入层叠样式表 jQuery和原生JS的入口函数 1.jQ在页面结构加载完毕就会执行 原生JS的入口函数是等图片.层叠 ...

  5. 一、python入门练习题

    题目: 练习1:华氏温度转摄氏温度. 练习2:输入圆的半径计算计算周长和面积. 练习3:输入年份判断是不是闰年. 答案: 练习1: """ 将华氏温度转换为摄氏温度 F ...

  6. SVN库迁移到GitHub

    创建新目录,cmd进入到新目录,执行如下命令: git svn init svn://10.10.10.10/net/QA_Dept git svn fetch git remote add orig ...

  7. shell基础之pxe批量部署

    通过安装及配置DHCP,tftp-server,xinetd,httpd,syslinux来实现批量安装Linux系统 #!/bin/bash #检查环境 se_state=`getenforce` ...

  8. MyBatis 延迟加载(十四)

    什么是延迟加载 延迟加载又叫懒加载,也叫按需加载,也就是说先加载主表信息,需要的时候,再去加载从表信息.代码中有查询语句,当执行到查询语句时,并不是马上去数据库中查询,而是根据设置的延迟策略将查询向后 ...

  9. c# sql在where查询语句中使用字符串变量与int型变量

    使用where语句访问数据库时where语句用上文中以及定义过的变量来查询. string sql3 = string.Format("update Ships set ContainerN ...

  10. 10.20 host:域名查询工具

    host命令 是用于查询DNS的工具,它可以将指定主机名称转换为IP地址. host命令的参数选项及说明 -a 显示详细的DNS信息-t 指定查询的域名信息类型,可以是"A".&q ...