Mysql join算法深入浅出
导语
联表查询在日常的数据库设计中非常的常见,但是联表查询可能会带来性能问题,为了调优、避免设计出有性能问题的SQL,在explain命令中,会显示用的是哪个join算法,学习一下join过程是非常有必要的
当执行下面这个SQL Join,在不同的情况下会产生不一样的复杂度
select * from user tb1 left join tb2 on tb1.field1 = tb2.field2
一 Simple Nested-Loop Join(简单的嵌套循环连接)
简单来说嵌套循环连接算法就是一个双层for 循环 ,通过循环外层表的行数据,逐个与内层表的所有行数据进行比较来获取结果,
会产生两张表的集合全匹配,也就是tb1有几条数据 * tb2有几条数据,数量会随着表大匹配的数量会非常大, 就是笛卡尔积

伪代码:
for(field1:tb1) {
for(field2:tb2) {
if(field2.equals(field2)) {
return true;
}
}
}
二 Block Nested-Loop Join(缓存块嵌套循环连接)
这个算法是Simple Nested-Loop Join(简单的嵌套循环连接)的一个优化,如果无法使用Index Nested-Loop Join的时候,数据库是默认使用的是Block Nested-Loop Join算法的 (也就是MySql在field2字段不是索引的情况下才默认是这个类型)
Block Nested-Loop Join 其优化思路是减少内层表的扫表次数。
Simple Nested-Loop Join(简单的嵌套循环连接)第一个for循环一次会加载一行数据,然后去第二个for循环逐行去匹配。
但是Block Nested-Loop Join会在第一个for循环加载几行数据,然后再去然后去第二个for循环逐行去匹配

注意:
- 是否开启Block Nested-Loop Join 算法
需要开启优化器管理配置的optimizer_switch的设置block_nested_loop为on 默认为开启,如果关闭则使用Simple Nested-Loop Join算法
-- 查看是否开启Block Nested-Loop Join 算法
Show variables like 'optimizer_switc%';

- join buffer 的大小
这个属性是一个MySql的调优手段
-- 查看join_buffer大小
Show variables like 'join_buffer_size%';
mysql> Show variables like 'join_buffer_size%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| join_buffer_size | 262144 |
+------------------+--------+
1 row in set (0.12 sec)
三 Index Nested-Loop Join(索引嵌套循环连接)
这个算法只有在 tb2.field2为唯一索引的时候,才使用,因为我们已经知道了,在tb2表中,只有一行数据,所以我们不需要完整的去对比tb2表,只要一行对比上了就可以返回了,极大的减少了对内层表的匹配次数。过程如下:

三 Hash join
这个算法,在MySql8之前是没有的。主要的思想是把tb2.filed1或者tb1.filed1(谁结果集小谁合适)中的所有的值,构建成散列表,所以它适用于on等值(=)的情况,在日常的数据库表设计中,我们大多部分也是on等值的情况。复杂度变成了 构建成散列表的复杂度 + tb1.filed1 N。
- 对于大数据量的表关联,Hash join算法速度更快,且不用索引
- 在内存中进行,内存超出
join_buffer_size%,会使用硬盘

四 Merge Join
这个算法,同样在MySql8之前是没有的。上面说到了Hash join是在等值(=)才会去使用的,那非等值(>,<,>=,<=),这种条件在Mysql8中是是否还是之前的循环算法,答案是NO,然而如果两表已经有序,用的是Merge Join。Merge Join在做非等值(>,<,>=,<=)对比的时候,一旦有行不符合条件就会不往下面再去执行的,因为对比之前就是有序的,下面的都是不符合条件的。

五 强制使用某个算法
强制使用嵌套循环连接STRAIGHT_JOIN,
SELECT *
FROM Table1
STRAIGHT_JOIN Table2
ON Table1.Column = Table2.Column;
强制使用哈希连接USE_HASH(e, d),
SELECT USE_HASH(e, d) *
FROM employees AS e
INNER JOIN departments AS d
ON e.department_id = d.department_id;
强制使用合并连接USE_MERGE(e, d),
SELECT USE_MERGE(e, d) *
FROM employees AS e
INNER JOIN departments AS d
ON e.department_id = d.department_id;
一般来说,我们是不用去选择使用什么join算法的,优化器会帮我们自动选择
Mysql join算法深入浅出的更多相关文章
- MySQL Join算法与调优白皮书(一)
正文 Inside君发现很少有人能够完成讲明白MySQL的Join类型与算法,网上流传着的要提升Join性能,加大变量join_buffer_size的谬论更是随处可见.当然,也有一些无知的PGer攻 ...
- MySQL Join算法与调优白皮书(二)
Index Nested-Loop Join (接上篇)由于访问的是辅助索引,如果查询需要访问聚集索引上的列,那么必要需要进行回表取数据,看似每条记录只是多了一次回表操作,但这才是INLJ算法最大 ...
- MySQL Join算法与调优白皮书(三)
Batched Key Access Join Index Nested-Loop Join虽好,但是通过辅助索引进行链接后需要回表,这里需要大量的随机I/O操作.若能优化随机I/O,那么就能极大的提 ...
- 关于join算法的四篇文章
MySQL Join算法与调优白皮书(一) MySQL Join算法与调优白皮书(二) MySQL Join算法与调优白皮书(三) MySQL Join算法与调优白皮书(四) MariaDB Join ...
- 022:SQL优化--JOIN算法
目录 一. SQL优化--JOIN算法 1.1. JOIN 写法对比 2. JOIN的成本 3. JOIN算法 3.1. simple nested loop join 3.2. index nest ...
- MySQL Nested-Loop Join算法学习
不知不觉的玩了两年多的MySQL,发现很多人都说MySQL对比Oracle来说,优化器做的比较差,其实某种程度上来说确实是这样,但是毕竟MySQL才到5.7版本,Oracle都已经发展到12c了,今天 ...
- Mysql的join算法
本文转载自Mysql的join算法 导语 在Mysql中,使用Nested-Loop Join的算法思想去优化join,Nested-Loop Join翻译成中文则是"嵌套循环连接" ...
- MySql联接算法
联接算法是MySql数据库用于处理联接的物理策略.在MySql 5.5版本仅支持Nested-Loops Join算法,如果联接表上有索引时,Nested-Loops Join是非常高效的算法.如果有 ...
- 1110Nested Loop Join算法
转自 http://blog.csdn.net/tonyxf121/article/details/7796657 join的实现原理 join的实现是采用Nested Loop Join算法,就是通 ...
- MySQL join的实现原理及优化思路
Join 的实现原理 在MySQL 中,只有一种Join 算法,也就是Nested Loop Join,没有其他很多数据库所提供的Hash Join,也没有Sort Merge Join.顾名思义,N ...
随机推荐
- Win10正式专业版激活方法
首先,我们先查看一下Win10正式专业版系统的激活状态: 点击桌面左下角的"Windows"按钮,从打开的扩展面板中依次点击"设置"-"更新和安全 ...
- Qt通用方法及类库8
函数名 //异或加密算法 static QString getXorEncryptDecrypt(const QString &str, char key); //异或校验 static uc ...
- [转]swing中如何将jtable中的数据导入到excel中?
这个版本的代码是可以支持中文,需要导入jxl.jar包,并添加到Build Path中(自行搜索下载). 最终代码: package test; import java.awt.event.*; im ...
- IM跨平台技术学习(十二):万字长文详解QQ Linux端实时音视频背后的跨平台实践
本文由QQ音视频团队贺坤分享原题"Linux QQ能打语音视频了!一文详解背后技术实现!",下文进行了排版和内容优化等. 1.引言 2024年6月6日,QQ For Linux 3 ...
- 百度高效研发实战训练营-Step1
百度高效研发实战训练营-Step1 1 设计方法与实践介绍 1.1. 软件设计原则 (1)软件设计的目的 软件设计是为了使软件在长期范围内能够容易的进行变化. 变化:软件不是一成不变的,无论是软件本身 ...
- JVM实战—9.线上FGC的几种案例
大纲 1.如何优化每秒十万QPS的社交APP的JVM性能(增加S区大小 + 优化内存碎片) 2.如何对垂直电商APP后台系统的FGC进行深度优化(定制JVM参数模版) 3.不合理设置JVM参数可能导致 ...
- Swagger UI、RESTful简介
Swagger UI 简介 Swagger UI允许任何人(无论您是开发团队还是最终用户)都可以可视化API资源并与之交互,而无需任何实现逻辑.它是根据您的OpenAPI(以前称为Swagger)规范 ...
- SpringBoot整合Netty+WebSocket
SpringBoot整合Netty+WebSocket 构建环境 pom.xml <?xml version="1.0" encoding="UTF-8" ...
- 使用binlog+canal或binlake进行数据库的复制
前言在进行冷热分离的时候,需要将数据实时的复制在历史数据库中,我们使用的是binlog+canal的思想,将每次数据库数据的变更转换成消息发出来,然后再操作这些消息达到数据复制的在京东,实现同样功能的 ...
- 项目PMP之三项目经理
一.项目经理定义:由执行组织委派,领导实现目标 二.影响范围: 项目本身:相关方沟通.完善各职能结构:通过人际关系和沟通技能及积极态度充当沟通者,以平衡项目相关方并达成共识 组织:组织结构中进行积极沟 ...