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 ...
随机推荐
- Qt数据库应用16-通用数据库采集
一.前言 数据库采集对应的就是上一篇文章的数据库同步,数据库同步到云端数据库以后,app.网页.小程序啥的要数据的话,可以通过执行http请求拿到数据,http接收应答这边程序一般最简单可以用php写 ...
- Qt开发经验小技巧176-180
QCamera中获取设备的配置参数比如支持的分辨率集合等,需要先调用load后才能正确获取,或者关联stateChanged信号中判断状态是否是ActiveState,然后再读取. //方法1:调用l ...
- 《Spring MVC+MyBatis快速开发与项目实战》-黄文毅2019:一书的源码和配套视频下载地址
<Spring MVC+MyBatis快速开发与项目实战>-黄文毅2019:一书的源码下载地址: http://github.com/huangwenyi10/springmvc-myba ...
- JMeter 采样器超详细教程
宝子们,今天咱就来好好唠唠 JMeter 里那些厉害的采样器,让你轻松拿捏性能测试和接口测试! 一.采样器大集合 先给宝子们来个采样器的 "全家福",让你们心里有个底: HTTP ...
- 十四款常见的Web前端开发框架
在做web开发的时候经常会遇到一个问题,那就是,选择什么样的框架来做前端开发.下面封程中把目前常用的一些前端的框架简单的给大家介绍一下. 1. BootstrapBoostrap绝对是目前最流行用得最 ...
- 基于Pamion的流实数仓架构
目录 1. 背景 2. 目标 3. Pamion 的概念和设计 3.1 架构 3.2 统一存储 3.3 基础概念 3.3.1 文件布局 3.3.2 Snapshot 3.3.3 Manifest 文件 ...
- Symbolic pg walkthrough Intermediate window 利用302进行文件csrf
nmap nmap -p- -A -sS -T4 192.168.239.177 Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-15 03:39 ...
- ZOS对象存储跨域资源访问的实现和使用
本文分享自天翼云开发者社区<ZOS对象存储跨域资源访问的实现和使用>,作者:对象存储二三事 跨域的定义 跨域指的是从一个域名去请求另外一个域名的资源,即跨域名请求.跨域时,浏览器不能执行其 ...
- Java获取数据库的列名、列数、标题、类型等信息, ResultSetMetaData
import java.sql.*; public class jdbcTest { public static void main(String[] args) throws ClassNotFou ...
- 「原创」Xiaomi-R3 免刷Openwrt实现路由器锐捷认证 (含网络守护脚本)
引言 没有路由器 宿舍人均用网络月末苦不堪言,搭建一台路由器燃眉之急!! 设备选择 初代小米路由器产品均为OpenWrt深度定制后的产物,免去设备刷入固件时机器变砖的风险,本片记录的使用型号为 MIR ...