Mysql优化_第十三篇(HashJoin篇)
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篇)的更多相关文章
- Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解
Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解 Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...
- MySQL优化/面试,看这一篇就够了
原文链接:http://www.zhenganwen.top/articles/2018/12/25/1565048860202.html 作者:Anwen~链接:https://www.nowcod ...
- Mysql优化_内置profiling性能分析工具
如果要进行SQL的调优优化和排查,第一步是先让故障重现,但是这个并不是这一分钟有问题,下一秒就OK.一般的企业一般是DBA数据库工程师从监控里找到问题.DBA会告诉我们让我们来排查问题,那么可能很多种 ...
- mysql的优化_第十一篇(查询计划篇)
Mysql优化(出自官方文档) - 第十一篇(查询计划篇) 目录 Mysql优化(出自官方文档) - 第十一篇(查询计划篇) 1 EXPLAIN Output Format EXPLAIN Join ...
- mysql优化之索引篇
对mysql优化是一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引.主键索引.唯一索引unique.全文索引] c: 分表技术(水平 ...
- Mysql优化(出自官方文档) - 第三篇
目录 Mysql优化(出自官方文档) - 第三篇 1 Multi-Range Read Optimization(MRR) 2 Block Nested-Loop(BNL) and Batched K ...
- Mysql优化(出自官方文档) - 第五篇
目录 Mysql优化(出自官方文档) - 第五篇 1 GROUP BY Optimization 2 DISTINCT Optimization 3 LIMIT Query Optimization ...
- Mysql优化(出自官方文档) - 第八篇(索引优化系列)
目录 Mysql优化(出自官方文档) - 第八篇(索引优化系列) Optimization and Indexes 1 Foreign Key Optimization 2 Column Indexe ...
- Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇)
目录 Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇) 1 Optimizing Data Size 2 Optimizing MySQL Data Types 3 Optimizing ...
随机推荐
- win10 下安卓源码同步小技巧
win10下,通过 清华镜像源 AOSP 可以快速拿到 100G 的 .repo 备份 然后 用 repo sync 就可以得到 安卓源码,爽不爽! 下载到win10 e盘下,用powershell ...
- 射线与空间内三角形的相交检测算法(Möller-Trumbore)的推导与实践
背景介绍(学习算法之前需要先了解) 射线与空间内三角形的相交检测是游戏程序设计中一个常见的问题,最典型的应用就是拾取(Picking),本文介绍一个最常见的方法,这个方法也是DirectX中采用的方法 ...
- .NET平台系列7 .NET Core 体系结构详解
系列目录 [已更新最新开发文章,点击查看详细] .NET Core 是基于.NET Framework 为基础,借鉴了其优秀的思想与强大的功能,经过重新设计与构建,实现了.NET Fram ...
- Django 请求和响应 request return
request.method 请求方法 request.get get请求信息 request.post post请求信息 request.path 请求路径 方法: requset.get_fu ...
- 通过Cloudflare开启全站https
Cloudflare 添加域名后,会自动生成通用证书,快速开启全站HTTPS,服务端不用做任何修改,还可以选择多种开启模式 一.注册Cloudflare账号 直接打开网站:https://www.cl ...
- Django(34)Django操作session(超详细)
前言 session: session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个概念.一个服务器存储授权信息的解 ...
- 使用 yum-cron 自动更新 Linux系统
使用 yum-cron 自动更新 Linux系统 Linux系统技术交流QQ群(1675603)验证问题答案:刘遄 我知道如何使用 yum 命令行 更新系统,但是我想用 cron 任务自动更新软件 ...
- python实现UDP通讯
Environment Client:Windows Server:KaLi Linux(VM_virtul) Network:Same LAN Client UDPClient.py #-*- co ...
- sed -n "29496,29516p" service.log:从29496行开始检索,到29516行结束
在工作中常用的Linux命令 javalinux 发布于 2019-07-24 约 11 分钟 前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://gith ...
- 002.Python数据类型
一 python语言注释 就是对代码的解释, 方便大家阅读代码用的 1.1 注释的分类 (1)单行注释 # print 在python2.x print "1" # print 在 ...