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 ...
随机推荐
- mysql:sql create database新建utf8mb4 数据库
create database sina default character set utf8mb4 collate utf8mb4_unicode_ci;或者是create database con ...
- Qt音视频开发31-qmedia内核qt5/qt6播放视频
一.前言 在qt5中的多媒体框架明显比qt4丰富了很多,使用也极其友好,提供的api接口非常简单明了,不需要像qt4中那样还需要绑定和创建路径之类的.同样也还是依赖本地解码器,qt6中的多媒体框架据说 ...
- Qt编写地图综合应用58-兼容多浏览器内核
一.前言 miniblink是一个追求极致小巧的浏览器内核项目,全世界第三大流行的浏览器内核控件.其基于chromium最新版内核,去除了chromium所有多余的部件,只保留最基本的排版引擎blin ...
- TensorRT-YOLO:灵活易用的 YOLO 部署工具
TensorRT YOLO TensorRT-YOLO 是一款专为 NVIDIA 设备设计的易用灵活.极致高效的YOLO系列推理部署工具.项目不仅集成了 TensorRT 插件以增强后处理效果,还使用 ...
- 直播系统聊天技术(八):vivo直播系统中IM消息模块的架构实践
本文由vivo互联网技术团队LinDu.Li Guolin分享,有较多修订和改动. 1.引言 IM即时消息模块是直播系统的重要组成部分,一个稳定.有容错.灵活的.支持高并发的消息模块是影响直播系统用户 ...
- 大模型复现实践记录-在linux环境4090GPU(24G)
chatglm-6b chatglm2-6b tigerbot-7b baichuan-7b vicuna
- bitset 学习笔记
引入 顾名思义, \(\texttt{bitset}\) 是用 \(\texttt{bit}\) 组成的 \(\texttt{set}\); 区别于普通的 \(\texttt{bool []}\) 或 ...
- ForkJoin全解2:forkjoin实际工作流程与实现
1.相关概念解释 1.1 "内部"和外部 当一个操作是在非ForkjoinThread的线程中进行的,则称该操作为外部操作.比如我们前面执行pool.invoke,invoke内又 ...
- 【java提高】---细则(2)
TreeSet(一) 一.TreeSet定义: 与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的. 1)TreeSet类概述 ...
- Docker开发实践:在windows 7中使用Docker for windows访问GUI
1 安装Docker for windows 1.1下载Docker for windows 从下面的网址中下载Docker for windows并安装. https://www.docker.co ...