本文转载自Mysql的join算法

导语

在Mysql中,使用Nested-Loop Join的算法思想去优化joinNested-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 JoinSNLJ,简单嵌套循环连接
  • Index Nested-Loop JoinINLJ,索引嵌套循环连接
  • Block Nested-Loop JoinBNLJ,缓存块嵌套循环连接

    在选择Join算法时,会有优先级,理论上会优先判断能否使用INLJBNLJ

    Index Nested-LoopJoin > Block Nested-Loop Join > Simple Nested-Loop Join

Simple Nested-Loop

简单嵌套循环连接实际上就是简单粗暴的嵌套循环,如果table1有1万条数据,table2有1万条数据,那么数据比较的次数=1万 * 1万 =1亿次,这种查询效率会非常慢。

所以Mysql继续优化,然后衍生出Index Nested-LoopJoinBlock 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位操作系统下申请大于4GJoin Buffer空间。
  • 使用Block Nested-Loop Join算法需要开启优化器管理配置的optimizer_switch的设置block_nested_loopon,默认为开启。

如何优化Join速度

  1. 用小结果集驱动大结果集,减少外层循环的数据量:
  2. 如果小结果集和大结果集连接的列都是索引列,mysql在内连接时也会选择用小结果集驱动大结果集,因为索引查询的成本是比较固定的,这时候外层的循环越少,join的速度便越快。
  3. 为匹配的条件增加索引:争取使用INLJ,减少内层表的循环次数
  4. 增大join buffer size的大小:当使用BNLJ时,一次缓存的数据越多,那么外层表循环的次数就越少
  5. 减少不必要的字段查询:
    • 当用到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算法的更多相关文章

  1. MySQL Nested-Loop Join算法学习

    不知不觉的玩了两年多的MySQL,发现很多人都说MySQL对比Oracle来说,优化器做的比较差,其实某种程度上来说确实是这样,但是毕竟MySQL才到5.7版本,Oracle都已经发展到12c了,今天 ...

  2. mysql 查询优化~join算法

    一简介:参考了几位师兄,尤其是M哥大神的博客,让我恍然大悟,赶紧记录下二 原理: mysql的三种算法 1 Simple Nested-Loop Join 将驱动表/外部表的结果集作为循环基础数据,然 ...

  3. 关于join算法的四篇文章

    MySQL Join算法与调优白皮书(一) MySQL Join算法与调优白皮书(二) MySQL Join算法与调优白皮书(三) MySQL Join算法与调优白皮书(四) MariaDB Join ...

  4. MySQL Join算法与调优白皮书(一)

    正文 Inside君发现很少有人能够完成讲明白MySQL的Join类型与算法,网上流传着的要提升Join性能,加大变量join_buffer_size的谬论更是随处可见.当然,也有一些无知的PGer攻 ...

  5. MySQL Join算法与调优白皮书(二)

    Index Nested-Loop Join   (接上篇)由于访问的是辅助索引,如果查询需要访问聚集索引上的列,那么必要需要进行回表取数据,看似每条记录只是多了一次回表操作,但这才是INLJ算法最大 ...

  6. 1110Nested Loop Join算法

    转自 http://blog.csdn.net/tonyxf121/article/details/7796657 join的实现原理 join的实现是采用Nested Loop Join算法,就是通 ...

  7. MySQL的JOIN(五):JOIN优化实践之排序

    这篇博文讲述如何优化JOIN查询带有排序的情况.大致分为对连接属性排序和对非连接属性排序两种情况.插入测试数据. CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_I ...

  8. Mysql Nested-Loop Join Algorithms

    MySQL在多表之间执行join时,利用一种nested-loop algorithm 或者其变种:(嵌套循环)  Nested-Loop Join Algorithm      一个简单的嵌套循环连 ...

  9. MySQL联接查询算法(NLJ、BNL、BKA、HashJoin)

    一.联接过程介绍 为了后面一些测试案例,我们事先创建了两张表,表数据如下:   1 2 3 4 CREATE TABLE t1 (m1 int, n1 char(1)); CREATE TABLE t ...

随机推荐

  1. Idea里面远程提交spark任务到yarn集群

    Idea里面远程提交spark任务到yarn集群 1.本地idea远程提交到yarn集群 2.运行过程中可能会遇到的问题 2.1首先需要把yarn-site.xml,core-site.xml,hdf ...

  2. C++类基本--随笔一

    #include <iostream> using namespace std; class Teacher { public: Teacher(int m=3,int n=2) { a= ...

  3. 封装各种生成唯一性ID算法的工具类

    /** * Copyright (c) 2005-2012 springside.org.cn * * Licensed under the Apache License, Version 2.0 ( ...

  4. Spring Security原理分析:系列集合

    Spring Security 工作原理概览:https://blog.csdn.net/u012702547/article/details/89629415 spring security执行原理 ...

  5. 坐下坐下,基本操作(ZooKeeper 操作篇)

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. Z ...

  6. three.js cannon.js物理引擎制作一个保龄球游戏

    关于cannon.js我们已经学习了一些知识,今天郭先生就使用已学的cannon.js物理引擎的知识配合three基础知识来做一个保龄球小游戏,效果如下图,在线案例请点击博客原文. 我们需要掌握的技能 ...

  7. ES6(四)用Promise封装一下IndexedDB

    indexedDB IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据,它可以被网页脚本创建和操作. IndexedDB 允许储存大量数据,提供查找接口,还能建立索引,这些都是 ...

  8. Spring MVC 处理一个请求的流程分析

    Spring MVC是Spring系列框架中使用频率最高的部分.不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分.因此程序员一定要熟练掌握MV ...

  9. P4755 Beautiful Pair (分治 + 主席树)

    题意:1e5的数组 计算有多少对 ai * aj <= max(ai ai+1...aj-1 aj) 题解:在处理这种涉及到区间极值的题时 好像是个套路分治 从级值中间分成两个区间 从区间短的那 ...

  10. Codeforces Round #652 (Div. 2) B. AccurateLee(字符串)

    题目链接:https://codeforces.com/contest/1369/problem/B 题意 给出一个长 $n$ 的 二进制串,每次可以选择字符串中的一个 $10$,然后删除其中的一个字 ...