MySQL中join连接,内连接,外连接,连接算法,优化

Posted Leo Han

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中join连接,内连接,外连接,连接算法,优化相关的知识,希望对你有一定的参考价值。

mysql中连接大致分为两类:

  • 内连接:驱动表的记录在被驱动表中找不到匹配的记录,该记录不会加入到最后的结果集(inner join
  • 外连接:驱动表的记录即使在被驱动表中找不到匹配的记录,也会加入到结果集(left [outer] joinright [outer] join

外连接又分为做外链接和右外连接

  • 左连接:选取左侧的表为驱动表
  • 右连接:选择右侧的表为驱动表

在MySQL中where条件不管内连接还是外连接都会过滤,对于on条件,内连接时on的作用和where条件是等价的,外连接的时候,on条件如果匹配不上,用NULL填充

可以看到,对于内连接,选取哪个表为驱动表是没有关系的

嵌套循环连接-Nested-Loop Join

对于两个表的连接处理,一般如下:

  1. 选取驱动表,从驱动表中读取需要的数据
  2. 对从驱动表中读取的每一条记录,到被驱动表中找到匹配的几率

这个过程就像是一个循环,驱动表只会访问一次,而被驱动表会访问多次

基于块的嵌套循环连接- Block Nested-Loop Join

MySQL中读取表一般都是把表从磁盘加载到内存中,然后在内存中比较条件是否满足。当我们进行join连接的时候,首先从驱动表中拿取一条记录,然后加载被驱动表的记录和驱动表的这条记录匹配,之后就会从内存中清除;然后在从驱动表中加载一条数据,再从被驱动表中加载记录和这条记录匹配,然后清除,如此循环。这样,每次匹配都需要从磁盘读取被驱动表,相当于要进行好几次IO从磁盘读取被驱动表,为此我们需要减少被驱动表访问的次数
因此MySQL中提出了Block Nested-Loop Join,处理逻辑为:
每次从驱动表中提取多条数据放在内存中,然后被驱动表每次和这个多条记录匹配,这样减少了被驱动表读取的次数。MySQL中存储这多条记录的地方称为join buffer
在MySQL配置文件中,通过join_buffer_size配置,默认为256KB,如果我们的join buffer足够大的话,一次将驱动表的所有记录都读取到join buffer中,那么只需要读取一次被驱动表就能完成所有的匹配

对于被驱动表来说,加快查询效率,如增加索引等。同时建议使用小表驱动大表方式进行连接查询。

以上是关于MySQL中join连接,内连接,外连接,连接算法,优化的主要内容,如果未能解决你的问题,请参考以下文章

mysql开发之join语句学习

MySQL left join right join inner join

Mysql 多表连接查询 inner join 和 outer join 的使用

MySQL 内连接与外连接

MySql的join(连接)查询 (三表 left join 写法)

mysql join 谁是驱动表