首页 > 数据库 >MySQL学习(7)连接的原理

MySQL学习(7)连接的原理

时间:2023-10-21 11:44:40浏览次数:40  
标签:记录 MySQL t2 t1 m1 原理 驱动 连接

什么是连接

连接就是把各个表中的记录都取出来进行依次匹配。若无过滤条件,连接查询的结果集中包含一个表中的每一条记录与另一个表中的每一条记录相互匹配的组合,这样的结果集称为笛卡尔积。

测试数据:

CREATE TABLE t1(m1 INT, n1 char(1));
CREATE TABLE t2(m2 INT, n2 char(1));
INSERT INTO t1 VALUES(1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO t2 VALUES(2, 'b'), (3, 'c'), (4, 'd');

 

两表连接示意图

连接的过程

SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';

 

这个查询中有3个过滤条件,分别是:

  • t1.m1 > 1

  • t1.m1 = t2.m2

  • t2.n2 < 'd'

连接查询中的过滤条件分为两种:

  • 单表条件:t1.m1 >1是t1表的过滤条件,t2.m2 < 'd'是t2表的过滤条件。

  • 两表条件:t1.m1 = t2.m2是两个表的过滤条件。

连接查询的过程如下:

  1. 首先确定第一个需要查询的表,称之为驱动表。

  2. 驱动表中美获取到一条记录,都需要到另一个表查找匹配到记录,这个表称之为被驱动表。

注意:驱动表只会被访问一次,每获得一条驱动表记录,就立即到被驱动表中寻找匹配记录,驱动表经过过滤条件后有多少条记录,就要访问多少次被驱动表。

内连接

对于内连接的两个表,若驱动表中的记录在被驱动表中找不到匹配记录,也就是不符合ON子句中的连接条件时,则该记录不会被加入到结果集。

SELECT * FROM t1 INNER JOIN t2 ON t1.m1 = t2.m2;

image-20231021113949352

内连接中不强制要求使用ON子句,因为此时ON和WHERE没啥区别,且驱动表和被驱动表可互换。

外连接

对于外连接的两个表,即使驱动表中的记录在被驱动表中没有找到匹配记录,也会加入到结果集,查询列表涉及到的被驱动的列显示NULL。

外连接分为左外连接与右外连接,必须使用ON子句之处连接条件,不可以省略。其中左外连接使用LEFT JOIN连接两表,左边为驱动表,右边为被驱动表;右外连接使用RIGHT JOIN连接两表,左边为被驱动表,右边为驱动表。

# 左外连接
SELECT * FROM t1 LEFT JOIN t2 ON t1.m1 = t2.m2; 

image-20231020231901547

# 右外连接
SELECT * FROM t1 RIGHT JOIN t2 ON t1.m1 = t2.m2; 

image-20231020231946768

左外连接和右外连接的驱动表和被驱动表不能互换,LEFT JOIN规定左边为驱动表,RIGHT JOIN规定右边为驱动表。

连接的原理

嵌套循环连接

驱动表只访问一次,但被驱动表却可能访问多次,且访问次数取决于对驱动表执行单表查询后的结果集中有多少条记录,这种连接执行方式称为嵌套循环连接(Nested-Loop Join)。

注意:从驱动表中得到了一条记录,就立即到被驱动表进行查询,如果得到了匹配到记录,就把组合后的记录发送给客户端。

在嵌套循环连接中,驱动表和被驱动表都要各自执行单表查询,这样可以利用索引提高查询效率。特别是被驱动表,若每次执行全表扫描,会非常慢。

基于块的嵌套循环连接

MySQL在执行连接查询前申请了一块固定大小的内存,叫做Join Buffer(连接缓冲区)。先把若干条驱动表结果集中的记录装在Join Buffer中,然后开始扫描被驱动表,每一条驱动表的记录一次性地与Join Buffer中的多条驱动表记录进行匹配。由于匹配过程全都是在内存中完成的,这样显著减少了I/O代价。加入了Join Buffer的嵌套循环连接算法称为基于块的嵌套循环连接算法。

Join Buffer的大小通过系统变量join_buffer_size设置,默认大小256KB。最好是为被驱动表加上合适的索引,如如果不能使用索引,并且机器的内存较大,可以调整join_buffer_size大小来优化连接查询性能。Join Buffer不会存放驱动表记录的所有列,只有查询列表中的列和过滤条件的列才会被放到Join Buffer中,所以尽量不要将无用的列加入到查询列表,这样会浪费Join Buffer可用内存。

 

阅读自《MySQL是怎样运行的》小孩子4919

标签:记录,MySQL,t2,t1,m1,原理,驱动,连接
From: https://www.cnblogs.com/haleyeung/p/17778709.html

相关文章

  • 如何保障MySQL和Redis的数据一致性?
    先抛一下结论:在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案。根据网上的众多解决方案,总结出6种,直接看目录:  不好的方案 1、先写MySQL,再写Redis   如图所示: 这是一副时序图,描述请求的先后调用顺序; ......
  • MySQL CASE()用法
    MySQL中的CASE表达式用于根据条件进行条件判断和返回多个可能的值。它允许在查询中执行简单的逻辑判断,并根据不同的条件返回不同的值或执行不同的操作。CASE表达式有两种形式:简单CASE和搜索CASE。简单CASE形式:CASEexpressionWHENvalue1THENresult1WHE......
  • MySQL IF()用法
    MySQL中的IF函数用于根据条件返回两个值中的一个。它可以应用于复杂查询和更新语句中,以便根据条件动态生成值。IF函数的语法如下:IF(condition,value_if_true,value_if_false)其中,condition是一个布尔表达式或一个返回布尔值的函数,value_if_true是条件为TRUE时返回......
  • Mysql FIND_IN_SET()用法
    MySQL中的FIND_IN_SET函数用于在逗号分隔的字符串列表中查找指定字符串的位置。它接受两个参数:要查找的字符串和逗号分隔的字符串列表。语法如下:FIND_IN_SET(string,string_list)其中,string是要查找的字符串,string_list是逗号分隔的字符串列表。返回值为待查找字符串......
  • 如何在CentOS中设置SSH连接?
    在CentOS中设置SSH连接,需要以下步骤:安装OpenSSH服务在终端中输入以下命令以安装OpenSSH服务:sudoyuminstallopenssh-server   2、启动OpenSSH服务安装成功后,执行以下命令启动OpenSSH服务:sudosystemctlstartsshd.service   3、设置开机自启动启动之后,需......
  • MySql 关键字 COALESCE
    MySQLCOALESCE()函数用于返回表达式列表中的第一个非空值。如果列表中的所有值均评估为NULL,则COALESCE()函数将返回NULL。COALESCE()函数接受一个参数,该参数是可以包含各种值的列表。MySQLCOALESCE()函数返回的值是表达式列表中的第一个非空值;如果列表中的所有值均为NULL,则为N......
  • MySql Json字段部分查询语法
    模糊匹配jsonObject字段select*fromtableNamewherecolumnName->'$.xx'like'%xx%'精确匹配jsonObject类型字段select*fromtableNamewherecolumnName->'$.xx'='xx'模糊匹配jsonArray字段select*fromtableNamewh......
  • 计算机组成原理之地址映像
    1、直接映像2、全相联映像3、组相联映像......
  • MySQL学习(6)单表访问方法
    什么是访问方法MySQL执行查询语句的方式称为访问方法(accessmethod)。单表的访问方法有哪些const通过主键或唯一二级索引列定位一条记录的方法叫const,这种方法要求主键列或者唯一二级索引列与一个常数进行等值比较时才有效。注意,使用唯一二级索引且搜索条件为ISNULL无效。例......
  • umicv cv-summary1-全连接神经网络模块化实现
    全连接神经网络模块化实现Linear与Relu单层实现LossLayer实现多层神经网络不同梯度下降方法Dropout层今天这篇博文针对Assignment3的全连接网络作业,对前面学习的内容进行一些总结在前面的作业中我们建立神经网络的操作比较简单,也不具有模块化的特征,在A3作业中,引导我们......