MSQL系列(九) Mysql实战-Join算法底层原理

这篇具有很好参考价值的文章主要介绍了MSQL系列(九) Mysql实战-Join算法底层原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Mysql实战-Join算法底层原理

前面我们讲解了B+Tree的索引结构,及Mysql的存储引擎MyISAM和InnoDB,今天我们来详细讲解下Mysql的查询连接Join的算法原理


Join算法分类
在Mysql的查询过程中,我们都知道涉及多表查询,我们都会使用join来连接多个表进行查询,join的本质就是循环每个表进行匹配,join算法可以分为三种形式
  1. 简单嵌套循环连接 SNL ( Simple Nested-Loop Join)
  2. 块嵌套循环连接 INL( Block Nested-Loop Join)
  3. 索引嵌套循环连接 INL( Index Nested-Loop Join)
1.Simple Nested-Loop Join 简单嵌套循环

Simple Nested-Loop join(NLJ)算法

  • 比较简单粗暴,就是通过双层循环比较数据来获取查询结果
  • 从循环中的第一个表中一次读取一行,将每一行传递给一个嵌套循环,判断嵌套循环中匹配数据是否一致

假如两个表,每个表都有1W条数据,那么数据对比次数就是 1w*1w=1亿次,每一次扫描其实就是从硬盘中读取数据加载到内存中,也就是一次IO,目前IO是最大的瓶颈, 查询效率相当的慢

例如 驱动表用户表User, 被驱动表class课程表

select * from User u left join  class c on u.id = c.user_id

相当于写了一个for循环来执行查询逻辑,伪代码可以看作

for(User u: User){
    for(Class c: Class){
        if(u.id == c.userId){
        //     得到匹配数据
        }
    }
}

可以用下面的图来简单的解释一下
MSQL系列(九) Mysql实战-Join算法底层原理,Mysql实战,mysql,join算法,Nested loop 算法,Mysql的join算法,Nested loop实现

2.Block Nested-Loop Join 块嵌套循环连接

我们知道上面的简单嵌套循环 效率很低是因为他必须扫描取每一条数据,者提供是非常耗时的,所以我们为啥不能多取一点呢?

Block Nested-Loop Join 块嵌套循环连接
不再是每条每条的取,而是每次都从驱动表每次取一批数据,放到内存中,然后对这一批数据进行匹配操作,当数据操作匹配完毕,就再次从驱动表中取一批数据放到内存中,再次比较,直到数据匹配完毕,完成查询,这种方式就是 块嵌套循环连接

Mysql中对这块内存有一个专门的名词就是 join buffer,我们可以通过执行

#查看join buffer大小
show variables like '%join_buffer%'

查询结果
MSQL系列(九) Mysql实战-Join算法底层原理,Mysql实战,mysql,join算法,Nested loop 算法,Mysql的join算法,Nested loop实现
那么我们的 Join Buffer有这么一个内存空间,这里面到底存储的是什么东西呢?假如我们查询2个表 a表和b表, 这里用到了

  • a表的 col1列,col2列,col3列
  • b表的 col1列 和 col2列

查询语句如下

select a.col1 from a
left join b 
on a.col2= b.col1
where a.col3 > 0 and b.col2 >0

查询过程分析

  • 首先扫描 驱动表,然后读取一定长度的数据存储到 join buffer中
  • join buffer中存储的不是驱动表的整行记录
  • join buffer中只会放驱动表参与查询的列, 也就是a表的 col1列,col2列,col3列
  • 查询的字段越少,join buffer存放的记录越多
  • 一次存放的记录越多,I/O查询的次数就越少,效率就越高
  • 对于 join buffer的大小,我们可以通过 设置去优化 设置为1M 命令 set session join_buffer_size = 1024*1024 * 1024

我们可以用下面的图来简单介绍下 块循环的逻辑
MSQL系列(九) Mysql实战-Join算法底层原理,Mysql实战,mysql,join算法,Nested loop 算法,Mysql的join算法,Nested loop实现

3. Index Nested-Loop Join 索引嵌套循环连接

上面我们讲解了 块嵌套循环连接,需要把驱动表的数据加入join buffer来进行匹配,同样非常耗时,我们有其他优化方法吗?这就引出了 Index Nested-Loop Join 索引嵌套循环连接

ndex Nested-Loop Join 索引嵌套循环连接
顾名思义就是必须有索引才行,而且是驱动表上必须有索引,通过使用索引减少扫描的次数来提高查询效率的

我们给驱动表 需要连接的列加上索引,这样匹配的过程就会非常的快

  • 首先 驱动表会根据关联字段的索引进行查询,当索引是否命中数据,直接进行回表查询该条记录
  • 驱动表会根据关联字段的索引进行查询,当索引上找到符合的值,才会进行回表查询
  • 如果非驱动表的关联字段是主键的话,查询效率非常高(主键索引结构的叶子结点包含了完整的行数据),
  • 非驱动表的关联字段如果不是主键,每次匹配到索引后都需要进行一次回表查询,性能弱于主键的查询

索引嵌套循环连接用可以用下面的图来简单描述
MSQL系列(九) Mysql实战-Join算法底层原理,Mysql实战,mysql,join算法,Nested loop 算法,Mysql的join算法,Nested loop实现


至此,我们彻底的了解了 join算法的底层原理,也明确直到了三种方法的优劣,有助于我们再分析索引的时候,更快的定位出问题,进行索引优化文章来源地址https://www.toymoban.com/news/detail-720193.html

到了这里,关于MSQL系列(九) Mysql实战-Join算法底层原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解MySQL中的Join算法

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 什么是Join Index Nested-Loop Join Block Nested-Loop Join MRR BKA 总结 在数据库处理中,Join操作是最基本且最重要的操作之一,它能将不同的表连接起来,实现对

    2024年02月08日
    浏览(45)
  • MYSQL 事务的底层原理

    在事务的实现机制上,MySQL 采用的是 WAL:Write-ahead logging,预写式日志,机制来实现的。 在使用 WAL 的系统中,所有的修改都先被写入到日志中,然后再被应用到系统中。通常包含 redo 和 undo 两部分信息。 为什么需要使用 WAL,然后包含 redo 和 undo 信息呢?举个例子,如果一个

    2024年02月05日
    浏览(49)
  • MySQL中的Join 的算法(NLJ、BNL、BKA)

    本文已收录至Github,推荐阅读 👉 Java随想录 微信公众号:Java随想录 目录 摘要 什么是Join Index Nested-Loop Join Block Nested-Loop Join MRR BKA 总结 Join是MySQL中最常见的查询操作之一,用于从多个表中获取数据并将它们组合在一起。Join算法通常使用两种基本方法:Index Nested-Loop Join(N

    2024年02月03日
    浏览(31)
  • innodb底层原理和MySQL日志机制

    客户端连接数据库需要输入账号、密码。连接器进行校验账号密码以及权限。 连接器连接以后,比如输入一个select语句,这时候第一步就会先根据sql语句作为key给查询缓存中查看这条sql有没有已经被查询过,如果有直接返回,如果没有就接着到分析器。查询缓存是以key-valu

    2024年01月24日
    浏览(51)
  • Innodb底层原理与Mysql日志机制深入剖析

    大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。 主要包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器

    2024年02月21日
    浏览(42)
  • MySQL实战解析底层---如何正确地显示随机消息

    目录 前言 内存临时表 磁盘临时表 随机排序方法 前言 现在说说MySQL中的另外一种排序需求,希望能够加深对MySQL排序逻辑的理解 从一个单词表中随机选出三个单词 这个表的建表语句和初始数据的命令如下: 为了便于量化说明,在这个表里面插入了10000行记录 接下来就要随机

    2024年02月10日
    浏览(84)
  • mysql与msql2数据驱动

    查询语句执行顺序 多表查询 将查询到的课程信息转化为json格式: 1.提高性能 将语句模块发送给mysql编译、优化、转换,然后存储它但不执行。之后传入实参时,真正执行。多次执行,也只编译一次。 2.防止sql注入

    2024年02月11日
    浏览(49)
  • 【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

    JVM系列整体栏目 内容 链接地址 【一】初识虚拟机与java虚拟机 https://blog.csdn.net/zhenghuishengq/article/details/129544460 【二】jvm的类加载子系统以及jclasslib的基本使用 https://blog.csdn.net/zhenghuishengq/article/details/129610963 【三】运行时私有区域之虚拟机栈、程序计数器、本地方法栈 https

    2023年04月22日
    浏览(76)
  • 【深入浅出RocketMQ原理及实战】「底层原理挖掘系列」透彻剖析贯穿RocketMQ的消息消费长轮训机制体系的原理分析

    使用系统控制读取操作的DefaultMQPushConsumer可以自动调用传入的处理方法来处理收到的消息。通过设置各种参数和传入处理消息的函数,使用DefaultMQPushConsumer的主要目的是方便配置和处理消息。在收到消息后,系统会自动保存Offset,并且如果加入了新的DefaultMQPushConsumer,系统会

    2024年02月11日
    浏览(45)
  • MySQL实战解析底层---“order by“是怎么工作的

    目录 前言 全字段排序 rowid排序 全字段排序 VS rowid排序 前言 在开发应用的时候,一定会经常碰到需要根据指定的字段排序来显示结果的需求 以举例市民表为例,假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前1000个人的姓名、年龄 假设这个表的部分定

    2024年02月10日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包