Mysql的join算法
本文转载自Mysql的join算法
导语
在Mysql中,使用Nested-Loop Join的算法思想去优化join,Nested-Loop Join翻译成中文则是“嵌套循环连接”。
举个例子:
select * from t1 inner join t2 on t1.id=t2.tid
t1称为外层表,也可称为驱动表。t2称为内层表,也可称为被驱动表。
//伪代码表示:
List<Row> result = new ArrayList<>();
for(Row r1 in List<Row> t1){
for(Row r2 in List<Row> t2){
if(r1.id = r2.tid){
result.add(r1.join(r2));
}
}
}
在Mysql的实现中,Nested-Loop Join有3种实现的算法:
Simple Nested-Loop Join:SNLJ,简单嵌套循环连接Index Nested-Loop Join:INLJ,索引嵌套循环连接Block Nested-Loop Join:BNLJ,缓存块嵌套循环连接
在选择Join算法时,会有优先级,理论上会优先判断能否使用INLJ、BNLJ:
Index Nested-LoopJoin>Block Nested-Loop Join>Simple Nested-Loop Join
Simple Nested-Loop
简单嵌套循环连接实际上就是简单粗暴的嵌套循环,如果table1有1万条数据,table2有1万条数据,那么数据比较的次数=1万 * 1万 =1亿次,这种查询效率会非常慢。
所以Mysql继续优化,然后衍生出Index Nested-LoopJoin、Block Nested-Loop Join两种NLJ算法。在执行join查询时mysql会根据情况选择两种之一进行join查询。
Index Nested-LoopJoin(减少内层表数据的匹配次数)
索引嵌套循环连接是基于索引进行连接的算法,索引是基于内层表的,通过外层表匹配条件直接与内层表索引进行匹配,避免和内层表的每条记录进行比较, 从而利用索引的查询减少了对内层表的匹配次数,优势极大的提升了 join的性能:
原来的匹配次数 = 外层表行数 * 内层表行数
优化后的匹配次数= 外层表的行数 * 内层表索引的高度
使用场景:只有内层表join的列有索引时,才能用到Index Nested-LoopJoin进行连接。
由于用到索引,如果索引是辅助索引而且返回的数据还包括内层表的其他数据,则会回内层表查询数据,多了一些IO操作。
Block Nested-Loop Join(减少内层表数据的循环次数)
缓存块嵌套循环连接通过一次性缓存多条数据,把参与查询的列缓存到Join Buffer 里,然后拿join buffer里的数据批量与内层表的数据进行匹配,从而减少了内层循环的次数(遍历一次内层表就可以批量匹配一次Join Buffer里面的外层表数据)。
当不使用Index Nested-Loop Join的时候,默认使用Block Nested-Loop Join。
什么是Join Buffer?
Join Buffer会缓存所有参与查询的列而不是只有Join的列。- 可以通过调整
join_buffer_size缓存大小 join_buffer_size的默认值是256K,join_buffer_size的最大值在MySQL 5.1.22版本前是4G,而之后的版本才能在64位操作系统下申请大于4G的Join Buffer空间。- 使用
Block Nested-Loop Join算法需要开启优化器管理配置的optimizer_switch的设置block_nested_loop为on,默认为开启。
如何优化Join速度
- 用小结果集驱动大结果集,减少外层循环的数据量:
- 如果小结果集和大结果集连接的列都是索引列,
mysql在内连接时也会选择用小结果集驱动大结果集,因为索引查询的成本是比较固定的,这时候外层的循环越少,join的速度便越快。 - 为匹配的条件增加索引:争取使用
INLJ,减少内层表的循环次数 - 增大
join buffer size的大小:当使用BNLJ时,一次缓存的数据越多,那么外层表循环的次数就越少 - 减少不必要的字段查询:
- 当用到
BNLJ时,字段越少,join buffer所缓存的数据就越多,外层表的循环次数就越少; - 当用到
INLJ时,如果可以不回表查询,即利用到覆盖索引,则可能可以提示速度。(未经验证,只是一个推论)
- 当用到
参考文档
https://www.wengbi.com/thread_99558_1.html
https://www.cnblogs.com/starhu/p/6418842.html
https://www.cnblogs.com/starhu/p/6418833.html
Mysql的join算法的更多相关文章
- MySQL Nested-Loop Join算法学习
不知不觉的玩了两年多的MySQL,发现很多人都说MySQL对比Oracle来说,优化器做的比较差,其实某种程度上来说确实是这样,但是毕竟MySQL才到5.7版本,Oracle都已经发展到12c了,今天 ...
- mysql 查询优化~join算法
一简介:参考了几位师兄,尤其是M哥大神的博客,让我恍然大悟,赶紧记录下二 原理: mysql的三种算法 1 Simple Nested-Loop Join 将驱动表/外部表的结果集作为循环基础数据,然 ...
- 关于join算法的四篇文章
MySQL Join算法与调优白皮书(一) MySQL Join算法与调优白皮书(二) MySQL Join算法与调优白皮书(三) MySQL Join算法与调优白皮书(四) MariaDB Join ...
- MySQL Join算法与调优白皮书(一)
正文 Inside君发现很少有人能够完成讲明白MySQL的Join类型与算法,网上流传着的要提升Join性能,加大变量join_buffer_size的谬论更是随处可见.当然,也有一些无知的PGer攻 ...
- MySQL Join算法与调优白皮书(二)
Index Nested-Loop Join (接上篇)由于访问的是辅助索引,如果查询需要访问聚集索引上的列,那么必要需要进行回表取数据,看似每条记录只是多了一次回表操作,但这才是INLJ算法最大 ...
- 1110Nested Loop Join算法
转自 http://blog.csdn.net/tonyxf121/article/details/7796657 join的实现原理 join的实现是采用Nested Loop Join算法,就是通 ...
- MySQL的JOIN(五):JOIN优化实践之排序
这篇博文讲述如何优化JOIN查询带有排序的情况.大致分为对连接属性排序和对非连接属性排序两种情况.插入测试数据. CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_I ...
- Mysql Nested-Loop Join Algorithms
MySQL在多表之间执行join时,利用一种nested-loop algorithm 或者其变种:(嵌套循环) Nested-Loop Join Algorithm 一个简单的嵌套循环连 ...
- MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)
一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下: 1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...
随机推荐
- 常见JVM面试题及答案整理
常见JVM面试题及答案整理 1.什么情况下会发生栈内存溢出 2.JVM内存模型 3.JVM内存为什么要分成新生代,老年代,持久代.新生代中为什么要分为Eden和Survivor. 3.1共享内存区划分 ...
- VMware虚拟机串口与宿主机进行传输验证
一.验证目的 1.验证VMWARE虚拟机(Windows或Linux)上的程序,是否可以读取宿主服务器的物理串口中的数据. 二.验证过程 1.验证条件及工具, 宿主机:Windows 10 x64 V ...
- 3.DHCP原理
1.DHCP服务器给首次接入网络的客户端分配网络参数的工作原理 只有跟DHCP客户端在同一个网段的DHCP服务器才能收到DHCP客户端广播的DHCP DISCOVER报文.当DHCP客户端与DHCP服 ...
- 【uva 11134】Fabled Rooks(算法效率--问题分解+贪心)
题意:要求在一个N*N的棋盘上放N个车,使得它们所在的行和列均不同,而且分别处于第 i 个矩形中. 解法:问题分解+贪心. 由于行.列不相关,所以可以先把行和列均不同的问题分解为2个"在区间 ...
- tju3243 Blocked Road
There are N seaside villages on X island, numbered from 1 to N. N roads are built to connect all of ...
- HDU 1173 思路题
题目大意 有n个地点(坐标为实数)需要挖矿,让选择一个地点,使得在这个地方建造基地,到n个地点的距离和最短,输出基地的坐标. 题解+代码: 1 /* 2 把这个二维分开看(即把所有点投影到x轴上,再把 ...
- Codeforces Round #658 (Div. 2) D. Unmerge (思维,01背包)
题意:有两个数组\(a\)和\(b\),每次比较它们最左端的元素,取小的加入新的数组\(c\),若\(a\)或\(b\)其中一个为空,则将另一个全部加入\(c\),现在给你一个长度为\(2n\)的数组 ...
- Python3.9.1中如何使用match方法?
接触编程的朋友都听过正则表达式,在python中叫re模块,属于文字处理服务里面的一个模块.re里面有一个方法叫match,接下来的文章我来详细讲解一下match. 作为新手,我建议多使用帮助文档,也 ...
- 基于CentOS-7的redis下载和安装
1.下载和安装 在我安装的虚拟机中,我把所有自己安装的软件都放在了/ph/install 目录下,具体以自己实际情况为准. [root@localhost ~]$ cd /ph/install #进入 ...
- Dapr是如何简化微服务的开发和部署
基于微服务设计模式的现代应用程序面临着一系列挑战.微服务需要有一个强大的服务发现机制来实现动态连接.它们需要松散耦合,实现自主性和独立缩放.微服务需要支持多种语言,其中每个服务都是以最合适的语言.框架 ...