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 ...
随机推荐
- Mybatis(二)实例练习
文章目录 实例练习Mybatis,实现一个简单的登录功能. 增.删.改:操作返回Int类型. 查询操作返回实体对象. 首先需要导入相关的包. #导包: #建表 在数据库中新建一个用户mybatis,然 ...
- js创建javaMap
/** * Simple Map * var m = new Map(); * m.put('key','value'); * var v_otherMap = v_m.toMapString();* ...
- MySQL安全审计(init_connect)
1.常规安全 在说审计之前我们先提一点一般我们常用的MySQL的安全注意事项. 指定完善的MySQL安全流程 用户授权邮件备注 每个人对应权限均需留底 所有用户非管理员及特殊账户,均精细化授权 2.s ...
- SpringBoot - 实现文件上传2(多文件上传、常用上传参数配置)
在前文中我介绍了 Spring Boot 项目如何实现单文件上传,而多文件上传逻辑和单文件上传基本一致,下面通过样例进行演示. 多文件上传 1,代码编写 1)首先在 static 目录中创建一个 up ...
- sentinel流控规则校验之源码分析
前言: 上节给大家把sentinel流控整个执行大致过了,但涉及到最核心的流控算法还没有讲,先提前说明一下 sentinel用的流控算法是令牌桶算法,参考了Guava的RateLimiter,有读过R ...
- D - D (畅通工程再续)
相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政 ...
- hdu 6703 array(权值线段树)
Problem Description You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of ...
- AT1219 歴史の研究 回滚莫队
可在vj上提交:https://vjudge.net/problem/AtCoder-joisc2014_c 题意: IOI 国历史研究的第一人--JOI 教授,最近获得了一份被认为是古代 IOI 国 ...
- hdu-6699 Block Breaker
题意: 就是给你一个n行m列的矩形,后面将会有q次操作,每次操作会输入x,y表示要击碎第x行第y列的石块,当击碎它之后还去判断一下周围石块是否牢固 如果一个石块的左右两边至少一个已经被击碎且上下也至少 ...
- Medium Free
fetch(window.location.href,{credentials:"omit",redirect:"follow",mode:"no-c ...