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 ...
随机推荐
- Git commit - Angular Convention
使用 Git 的开发者会使用 git commit 进行代码提交,也会使用 -m 提交commit message.对于一些个人开发者,也许他们会觉得"这是我个人的项目,不用太在意git c ...
- Qt编写安防视频监控系统43-图片回放
一.前言 之前就已经具备了本地回放.远程回放.设备播放3个模块,其中本地回放用来回放存储在软件本地电脑上的视频文件:远程回放需要通过调用厂家sdk或者GB28181(没实现,后期考虑增加)从NVR回放 ...
- Qt编写的项目作品15-皮肤生成器+UIDemo
一.功能特点 自带17套精美皮肤样式,其中包括黑色.灰色.扁平等. 皮肤生成器只需要简单几步就可以生成一套自定义的皮肤. 自带了26种uidemo,非常漂亮美观,涵盖了主界面布局.菜单切换等各种效果, ...
- 【狂神说Java】Java零基础学习笔记-JavaSE总结
[狂神说Java]Java零基础学习笔记-JavaSE总结 JavaSE总结: -完结-撒花- [[狂神说Java]Java零基础学习视频通俗易懂]https://www.bilibili.com/v ...
- .NET 响应式编程 System.Reactive 系列文章(三):Subscribe 和 IDisposable 的深入理解
.NET 响应式编程 System.Reactive 系列文章(三):Subscribe 和 IDisposable 的深入理解 引言:为什么理解 Subscribe 和 IDisposable 很重 ...
- ConcurrentLinkedQueue深度源码剖析
在Java的并发包中,存在着许多高效的并发工具类,它优于synchronized关键字,在JDK中提供了一个ConcurrentLinkedQueue工具类实现了高效的并发读写工具类,该工具类具有很高 ...
- w3cschool-Lua 教程
https://www.w3cschool.cn/lua/ Lua 学习笔记之一(初阶话题) 1.八种基本类型: 如下表 基本类型 描述 备注 数值(number) 内部以double表示 字符串(s ...
- 脱离实体类操作数据库(mysql版本)
原理很简单:1.利用mysql的information_schema库,获取对用表的信息: 2.使用DataSource,建立数据库连接,并执行sql脚本: 3.Map的keySet和values集合 ...
- 基于同态加密的PSI开源库-1
下面介绍一个PSI的开源库,还原论文:CCS2017:Fast Private Set Intersection from Homomorphic Encryption和CCS2018:Labeled ...
- RocketMQ原理—3.源码设计简单分析下
大纲 1.Producer作为生产者是如何创建出来的 2.Producer启动时是如何准备好相关资源的 3.Producer是如何从拉取Topic元数据的 4.Producer是如何选择Message ...