MySQL中的驱动表与被驱动表及含义

 更新时间:2023年10月13日 14:10:08   作者:明年就当百万富翁  
使用join连接查询时如果有where条件,则MySQL执行器会根据查询条件过滤后的结果自动选择驱动表或被驱动表,这篇文章主要介绍了MySQL的驱动表与被驱动表,需要的朋友可以参考下

驱动表与被驱动表的含义

在MySQL中进行多表联合查询时,MySQL会通过驱动表的结果集作为基础数据,在被驱动表中匹配对应的数据,匹配成功合并后的临时表再作为驱动表或被驱动表继续与第三张表进行匹配合并,直到所有表都已匹配完毕,最后将结果返回出来。匹配算法:Nested-Loop Join(嵌套循环连接),在MySQL中有三种具体的实现算法:

  • Simple Nested-Loop Join:简单嵌套循环连接
  • Index Nested-Loop Join:索引嵌套循环链接
  • Block Nested-Loop Join:缓存快嵌套循环链接

Simple Nested-Loop Join

简单嵌套循环连接实际上就是简单粗暴的嵌套循环,如果驱动表有100条数据,被驱动表有100条数据,那么在匹配时会将驱动表的每一条数据作为匹配条件去被驱动表中逐个比较,实际上就要比较100*100=10000次,可以想象这种比较效率是非常低下的。

Index Nested-Loop Join

索引嵌套循环连接是基于被驱动表的索引进行连接的算法,通过驱动表的匹配条件与被驱动表的索引进行匹配,避免和每条记录比较,从而利用索引的查询减少匹配次数,提高查询的性能。但要注意的是被驱动表的关联条件必须要有索引时才能用到Index Nested-Loop Join。另外由于用到索引,如果是非聚簇索引并且查询的数据包含了被驱动表的其他字段,则会回到被驱动表再查询一次对应的数据,即回表,多了IO操作。

Block Nested-Loop Join

缓存嵌套循环连接通过一次性缓存多条驱动表数据、参与查询的列到Join Buffer里,然后拿Join Buffer里的数据批量与被驱动表中的数据进行比较,从而减少了循环匹配次数。

关于Join Buffer

Join Buffer会缓存所有参与查询的列,而不是只有Join的匹配列

可以调整MySQL的join_buffer_size缓存大小,join_buffer_size的默认值是256K,最大值在MySQL 5.1.22版本前是4G,而之后的版本才能在64位操作系统下申请大于4G的空间

要使用Block Nested-Loop Join算法需要开启优化器管理配置的optimizer_switch的设置block_nested_loop为on,默认为on

当查询优化器不使用Index Nested-Loop Join算法的时候,默认使用Block Nested-Loop Join算法。

联合查询的性能优化原则

明白联合查询的原理是驱动表与被驱动表通过条件嵌套循环连接匹配后,查询性能优化的思路就是:减少循环比较次数。可以通过以下几个原则来进行优化。

1. 以数据量小的表作为驱动表,数据量大的表作为被驱动表。

通过上面的分析可以得知,MySQL在联合查询中是用驱动表的数据作为筛选条件在被驱动表中进行匹配,所以假设table1作为驱动表,数据有10000条,table2作为被驱动表的数据有100条,并且被table2中有索引,那么用Index Nested-Loop Join算法进行匹配时要进行10000次的关联操作。但如果反过来用table2作为驱动表,table1作为被驱动表,只需要进行100次关联即可完成匹配,效率也会大大提高,其他的连接算法也类似。简单说通常情况下要用小表驱动大表。
但是这里的小表和大表是根据查询条件相对而言的,大小的计算是要根据查询条件和具体的字段进行衡量,假如查询条件指定了table1的搜索范围,即table1满足查询条件的行数有90行,那么计算公式为:90乘以参与关联查询字段的大小总和,若结果小于table2满足查询条件后的行数乘以参与关联查询字段的大小,则table1为小表,否则table1为大表。

2. 为匹配的条件增加索引

匹配的条件字段列尽量使用有索引的,争取使用Index Nested-Loop Join算法进行关联,减少被驱动表的循环次数

3. 增大join_buffer_size的大小

当使用Block Nested-Loop Join算法时,增大join_buffer_size的大小可以使驱动表一次缓存更多的数据,从而减少总体循环匹配的次数

4. 减少不必要的字段查询

  • 当用到Block Nested-Loop Join算法时,字段越少,join Buffer所缓存的数据就越多,那么循环的次数就越少。
  • 当用到Index Nested-Loop Join算法时,如果可以不回表查询,即只查询索引列,利用覆盖索引则可能提升匹配效率

如何确定驱动表与被驱动表

  • 在使用join连接并且无where条件时:

    left join左边的表为驱动表,右边的为被驱动表

    right join右边的表为驱动表,左边的为被驱动表

    使用join时,MySQL会自动判断左右两边哪边是小表,哪边是大表。小表作为驱动表,大表作为被驱动表,小表与大表的判断原则为上面讲到的根据行数和参与关联的字段计算得出。

  • 在使用in\exists时

    使用in时,驱动表和被驱动表由MySQL的执行器根据表的大小自动选择

    使用exists时,外部表为驱动表,内部表为被驱动表。无论加什么查询条件都无法改变

使用join连接查询时如果有where条件,则MySQL执行器会根据查询条件过滤后的结果自动选择驱动表或被驱动表。

到此这篇关于MySQL的驱动表与被驱动表的文章就介绍到这了,更多相关MySQL驱动表与被驱动表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL 外键(FOREIGN KEY)用法案例详解

    MySQL 外键(FOREIGN KEY)用法案例详解

    这篇文章主要介绍了MySQL 外键(FOREIGN KEY)用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 利用frm和ibd文件恢复mysql表数据的详细过程

    利用frm和ibd文件恢复mysql表数据的详细过程

    总是遇到mysql服务意外断开之后导致mysql服务无法正常运行的情况,使用Navicat工具查看能够看到里面的库和表,但是无法获取数据记录,提示数据表不存在,所以本文给大家介绍了利用frm和ibd文件恢复mysql表数据的详细过程,需要的朋友可以参考下
    2024-04-04
  • MySQL查询in操作 查询结果按in集合顺序显示

    MySQL查询in操作 查询结果按in集合顺序显示

    MySQL 查询in操作,查询结果按in集合顺序显示的实现代码,需要的朋友可以参考下。
    2010-12-12
  • MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错问题及解决方案

    MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错问题及解决方案

    这篇文章主要介绍了MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错问题及解决方案,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • 一文搞懂MySQL索引所有知识点

    一文搞懂MySQL索引所有知识点

    这篇文章主要带你搞懂MySQL索引的所有知识点,我们通常所说的索引,包括聚焦索引、覆盖索引、组合索引、前缀索引、唯一索引等,没有特别说明,默认都是使用B+树结构组织,感兴趣的小伙伴可以参考阅读
    2023-03-03
  • MySQL中库的基本操作指南(推荐!)

    MySQL中库的基本操作指南(推荐!)

    MySQL这个数据库是一个客户端-服务器结构的程序,下面这篇文章主要给大家介绍了关于MySQL中库的基本操作指南,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • 浅谈MySQL数据查询太多会OOM吗

    浅谈MySQL数据查询太多会OOM吗

    本文主要介绍了浅谈MySQL数据查询太多会OOM吗?文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • mysql 数据库安装经验问题汇总

    mysql 数据库安装经验问题汇总

    这篇文章主要介绍了mysql 数据库安装经验问题汇总,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Mysql如何删除数据库表中的某一列

    Mysql如何删除数据库表中的某一列

    这篇文章主要介绍了Mysql如何删除数据库表中的某一列,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 在MySQL中创建带有IN和OUT参数的存储过程的方法

    在MySQL中创建带有IN和OUT参数的存储过程的方法

    这篇文章主要介绍了在MySQL中创建带有IN和OUT参数的存储过程的方法,在一定程度上简化了操作,需要的朋友可以参考下
    2015-06-06

最新评论