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 ...
随机推荐
- cocos2d-x 调试问题
1.昨天一个新功能,在xcode模拟器上测试没问题.后来打包安卓后,一直有问题 就又添加日志功能 # define CCLOGFUNC(s) ...
- java开发工具一个很好的注释模板
<?xml version="1.0" encoding="UTF-8" standalone="no"?><templa ...
- 18.RAID介绍和部署磁盘阵列
1.RAID RAID(Redundant Array of Independent Disks,独立冗余磁盘阵列)技术具备的冗余备份机制以及提升了的硬盘吞吐量. 1)RAID 0:把多块物理硬盘设备 ...
- GLIBC升级
GLIBC升级 1.安装 1.1 说明 目前大部分架构都已经是GLIBC2.14了,难免会有一些老的机器会是GLIBC2.12,所以下面是我升级GLIBC的过程及步骤. GLIBC是系统核心服务,升级 ...
- HDU6331 Problem M. Walking Plan【Floyd + 矩阵 + 分块】
HDU6331 Problem M. Walking Plan 题意: 给出一张有\(N\)个点的有向图,有\(q\)次询问,每次询问从\(s\)到\(t\)且最少走\(k\)条边的最短路径是多少 \ ...
- 最短路径问题---Floyed(弗洛伊德算法),dijkstra算法,SPFA算法
在NOIP比赛中,如果出图论题最短路径应该是个常考点. 求解最短路径常用的算法有:Floyed算法(O(n^3)的暴力算法,在比赛中大概能过三十分) dijkstra算法 (堆优化之后是O(MlogE ...
- Luogu U13059 某种密码
应该没什么用的题目链接 题目背景 关于某种密码有如下描述:某种密码的原文A是由N个数字组成,而密文B是一个长度为N的01数串,原文和密文的关联在于一个钥匙码KEY.若KEY=∑▒[Ai*Bi],则密文 ...
- AC自动机——看似KMP在跑,其实fail在跳
先存代码 AC自动机(简单版) #include<bits/stdc++.h> #define maxn 1000007 using namespace std; int n,ans; i ...
- P1073 最优贸易(最短路)
题目描述 CC C国有n n n个大城市和m mm 条道路,每条道路连接这 nnn个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 mmm 条道路中有一部分为单向通行的道路,一部分为 ...
- Proud Merchants HDU - 3466 01背包&&贪心
最近,我去了一个古老的国家.在很长一段时间里,它是世界上最富有.最强大的王国.结果,这个国家的人民仍然非常自豪,即使他们的国家不再那么富有.商人是最典型的,他们每个人只卖一件商品,价格是Pi,但是如果 ...