浅谈mysql join底层原理

 更新时间:2021年08月03日 09:37:47   作者:java叶新东老师  
本文文章主要介绍了浅谈mysql join底层原理,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

join算法

mysql只支持一种join算法:Nested-Loop Join(嵌套循环连接),但Nested-Loop Join有三种变种:

  • Simple Nested-Loop Join,简单嵌套
  • Index Nested-Loop Join,索引嵌套
  • Block Nested-Loop Join ,join buffer缓冲区嵌套(临时表)

驱动表和非驱动表的区别

驱动表就是主表,非驱动表就是从表,看以下sql就知道了,A就是驱动表,B就是非驱动表。

select * from A left join B

A join B 连表时,一定先查A表再查B表吗?

答案是不一定,因为mysql内部有一个优化器,它会根据你查询语句做一些优化,先查哪张表也是由优化器决定的,但可以肯定的是,先查询的那张表就是驱动表,反之就是非驱动表;关于是那张表先查的问题,我们通过看执行计划来得出结果;在前面加上explain关键字即可;

explain select * from A join B;

1、Simple Nested-Loop Join,简单嵌套-无索引的情况

A left join B: ,每次都是全表匹配,A表的每行数据都全表匹配一次B表,也就是说,假如我A表有10条数据,B表有1000条数据,那么查询的时候扫描次数就是10*1000,也就说查询时需要扫描10000遍才能得出数据;

2、Index Nested-Loop Join-有索引的情况

select * from A join B on A.id=B.id where A.id = 1:在查询时,驱动表A会根据关联字段的索引进行查找,当在索引上找到符合的值,在回表进行查询,也就是说得匹配到索引后才会才会进行回表查询;
如果非驱动表B的关联关联字段B.id是主键的话,性能会非常高,如果不是主键,会进行多次回表查询,先关联索引,然后根据二级索引的主键id进行回表查询,性能上比主键要慢;

3、Block Nested-Loop Join ,join buffer缓冲区

如果有索引,会选取Index Nested-Loop Join进行连表,如果join列没有索引,就会采用Block Nested-Loop Join ,join buffer,在驱动表和非驱动表中间有个buffer的缓冲区,在查询时先将驱动表的数据缓存到buffer缓冲区内,然后批量与非驱动表进行匹配,这是一种将多次比较合并为一次比较的优化方案,注意:这里缓存的不只是关联表的列,select 后面的列也会缓存起来;

缓冲区大小

默认情况下buffer缓冲区join_biffer_size的容量为256k,如果说你的数据空间大于256k,就无法使用缓冲区了,转为最简单的循环嵌套Simple Nested-Loop Join,但是我们可以手动调整缓冲区大小来装入大容量的数据;查看join_biffer_size的sql:show variables like '%join_biffer_size%'

数据量大的表和数据量小的表如何选择连接顺序

最好由小表去连接大表,这样会减少扫描次数;比如大表有1000条数据,小表只有10条数据,那么最好的连接方式为:小表 join 大表;为什么要这么做呢?

  • 如果是大表 join 小表,假如我们的数据在大表的第999行,那么查询数据的时候就至少得扫描999次才能查出来;
  • 如果是小表 join 大表,假如我们的数据在小表的第9行,

细节

  • 连表查询的时候,最好不要超过三张表,因为需要join的字段,数据类型必须一致
  • 优先使用内连接来连表,外连接查询数据消耗的性能比内连接要高;
  • 确保关联查询中on 后面的列或者 using()中的字段带有索引,连表时可加快数据访问

到此这篇关于浅谈mysql join底层原理的文章就介绍到这了,更多相关mysql join底层原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql数据库日志binlog保存时效问题(expire_logs_days)

    mysql数据库日志binlog保存时效问题(expire_logs_days)

    这篇文章主要介绍了mysql数据库日志binlog保存时效问题(expire_logs_days),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • windows10安装mysql5.7.18教程

    windows10安装mysql5.7.18教程

    windows10安装mysql5.7.18是这样安装的吗?这篇文章主要为大家详细介绍了win10下mysql5.7.18安装配置方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 在MySQL中奏响数据库操作的乐章(推荐)

    在MySQL中奏响数据库操作的乐章(推荐)

    本文详细介绍了如何在MySQL中进行数据库操作,包括创建、删除、修改数据库等,以及如何使用字符集和校验规则,以及备份和恢复数据库的方法,同时,还讨论了如何查看和修改数据库的结构和数据,总的来说,本文为读者提供了一份全面的MySQL数据库操作指南
    2024-10-10
  • mySQL中in查询与exists查询的区别小结

    mySQL中in查询与exists查询的区别小结

    最近被一个朋友问到mySQL中in查询和exists的区别,当然只是草草的回答了下,今天偶然看到了一篇关于mysql中的exists查询的文章,读完感觉太”冷落”它了,这里总结一下,也跟自己常用的in查询做一下对比。有需要的朋友们可以参考借鉴,下面来一起学习学习吧。
    2016-11-11
  • MySQL存储引擎MyISAM与InnoDB区别总结整理

    MySQL存储引擎MyISAM与InnoDB区别总结整理

    今天小编就为大家分享一篇关于MySQL存储引擎MyISAM与InnoDB区别总结整理,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Access数据库的存储上限

    Access数据库的存储上限

    Access数据库的存储上限...
    2006-09-09
  • MySql服务器系统变量和状态变量介绍

    MySql服务器系统变量和状态变量介绍

    这篇文章主要介绍了MySql服务器系统变量和状态变量介绍,本文分别讲解了它们的作用、设置方法和获取方法,需要的朋友可以参考下
    2014-12-12
  • 详解如何使用DockerHub官方的MySQL镜像

    详解如何使用DockerHub官方的MySQL镜像

    MySQL是一个广泛使用的开源关系型数据库,那如何获取Mysql Docker镜像?下面通过这篇文章来一起看看如何使用DockerHub官方的MySQL镜像,有需要的朋友们可以参考借鉴。
    2016-12-12
  • 深入了解MySQL ClickHouse中的物化视图功能

    深入了解MySQL ClickHouse中的物化视图功能

    MapReduce是一种用于处理大规模数据集的并行编程模型,其特点高效性和可扩展性,这篇文章主要介绍了MySQL ClickHouse中的物化视图功能,需要详细了解可以参考下文
    2023-05-05
  • MySQL基础入门教程之事务

    MySQL基础入门教程之事务

    事务主要用于处理操作量大,复杂度高的数据,下面这篇文章主要给大家介绍了关于MySQL基础入门教程之事务的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04

最新评论