【Mysql】表连接的原理

狂神说docker(最全笔记) 一.Docker入门 1. Docker 为什么会出现 2. Docker的历史 3.Docker最新超详细版教程通俗易懂 Docker是基于Go语言开发的!开源项目 官网 官方文档Docker文档是超详细的 仓库地址 4. 虚拟化技术和容器化技术对比 4.1. 虚拟化技术的缺点 资源占用十分多 冗余步骤多 启动很慢 2.2. 容器化技术 比较Docker和虚拟化技术的不同 传统虚拟机, 虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软. 阅读详情

通过《初探表连接的原理》我们重新认识了下表的连接内连接外连接等概念。
下面深入连接的原理以及连接的算法实现。

嵌套循环连接

表进行内连接的时候,会根据查询成本选择一个优先访问的表作为驱动表(外连接,则是指定了驱动表),然后根据驱动表的查询结果再去被驱动表中查询,对驱动表只会进行一次查询,而对被驱动表的查询则是根据驱动表中查询的结果数,进行循环查询。
这就是嵌套循环中的循环操作,那嵌套呢
我们也会有多表连接的情况,在进行多表连接的时候,比如t1,t2,t3进行连接,先从驱动表 t1中查询出符合条件的数据,然后在循环遍历查询t2,循环的次数等于t1表中查询出的结果数,然后再将t1t2连表查询的结果作为新的驱动表,t3作为新的被驱动表,根据t1t2的结果数,循环查询t3

举个🌰

我们还是把昨天的表结构拿过来

# 创建两个表t1,t2
CREATE TABLE t1 (m1 int, n1 char(1));
CREATE TABLE t2 (m2 int, n2 char(1));
CREATE TABLE t3 (m3 int, n3 char(1));
# 向t1,t2中插入几条数据
INSERT INTO t1 VALUES(1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO t2 VALUES(2, 'b'), (3, 'c'), (4, 'd');
INSERT INTO t3 VALUES(4, 'd'), (5, 'e'), (6, 'f');

#表结构
mysql> select * from t1;
+------+------+
| m1   | n1   |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from t2;
+------+------+
| m2   | n2   |
+------+------+
|    2 | b    |
|    3 | c    |
|    4 | d    |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from t3;
+------+------+
| m3   | n3   |
+------+------+
|    4 | d    |
|    5 | e    |
|    6 | f    |
+------+------+
3 rows in set (0.00 sec)

执行连接查询

mysql> select * from t1,t2,t3 where t1.m1>1 and t1.m1=t2.m2 and t2.n2<'d' and t3.m3>t2.m2;
+------+------+------+------+------+------+
| m1   | n1   | m2   | n2   | m3   | n3   |
+------+------+------+------+------+------+
|    3 | c    |    3 | c    |    4 | d    |
|    2 | b    |    2 | b    |    4 | d    |
|    3 | c    |    3 | c    |    5 | e    |
|    2 | b    |    2 | b    |    5 | e    |
|    3 | c    |    3 | c    |    6 | f    |
|    2 | b    |    2 | b    |    6 | f    |
+------+------+------+------+------+------+
6 rows in set (0.00 sec)

因为我们没有建立索引,所以两个表的访问方式都是all 全表扫描,我们假定t1表作为驱动表t2表作为被驱动表。查询的过程大致如下:

for each row in t1 {   #此处表示遍历满足对t1单表查询结果集中的每一条记录
    
    for each row in t2 {   #此处表示对于某条t1表的记录来说,遍历满足对t2单表查询结果集中的每一条记录
    
        for each row in t3 {   #此处表示对于某条t1和t2表的记录组合来说,对t3表进行单表查询
            if row satisfies join conditions, send to client
        }
    }
}

这就是嵌套循环连接,也是连接算法中最简单的实现,当然也是很笨拙的一种实现方式。
试想如果我们的连接的表中有十万百万千万条数据,那么循环嵌套连接的算法会遍历多少条数据?又谈什么性能呢?所以有下面这种处理

使用索引加速连接查询速度

在上面的嵌套循环查询中,在循环查询被驱动表的时候,每一次的查询可以看作对被驱动表的一次查询。比如:

select * from t1,t2 where t1.m1>1 and t1.m1=t2.m2;

#先在t1表中查询出t1.m1>1的数据
+------+------+
| m1   | n1   |
+------+------+
|    2 | b    |
|    3 | c    |
+------+------+
# 然后在查询t2被驱动表时,可以理解成以下过程
# 第一次查询
select * from t2 where t2.m2=2;
# 第二次查询
select * from t2 where t2.m2=3;

如果t2表恰巧给m2建立了索引,那么以上对于t2表的访问方式就不是all全表扫描而变成ref级别,如果m2是唯一二级索引或者主键索引,那么访问级别就可以达到const(在连表查询中 叫做eq_ref,在对单表的访问中使用主键索引或者唯一二级索引叫做 const);
如果增加范围查询条件呢?

select * from t1,t2 where t1.m1>1 and t1.m1=t2.m2 and t2.n2<'f';

主要的查询步骤和上面的差不多,只是在对t2表进行查询的时候,多了t2.n2<'f’的查询条件,如果n2列也建立索引那么访问级别就可能达到range,即使n2没有建立索引或者索引未生效,那么此时的访问级别也是eq_ref+回表查询,这样的查询方式比all全表扫描要快出不少

所以,我们在做连表查询的时候要尽量使用索引,不要select * ,这样可以加快我们连表查询的速度;

基于块的嵌套循环查询

在进行表连接查询的时候,会经历循环嵌套查询,在实际的查询过程中,会将扫描表加载到内存中,然后在内存中查找符合条件的记录。如果我们连接的表有上百万千万的数据,那么这种做法很有可能会导致内存不足,所以,mysql设计有一个join buffer的概念:

join buffer就是执行连接查询前申请的一块固定大小的内存,先把若干条驱动表结果集中的记录装在这个join buffer中,然后开始扫描被驱动表,每一条被驱动表的记录一次性和join buffer中的多条驱动表记录做匹配,因为匹配的过程都是在内存中完成的,所以这样可以显著减少被驱动表的I/O代价

嵌套循环连接有什么区别呢?
循环嵌套连接驱动表中查询符合条件的结果集后,每次访问被驱动表被驱动表的数据会加载到内存中,然后被驱动表中的每一条记录只会与驱动表中的一条记录进行比较,然后就会在内存中清除,重复此过程。

如果join buffer 的空间足够大,能容纳从驱动表中查询的所有结果集,那么只需要访问一次被驱动表就能完成数据筛选的过程了。

mysql中提供了相应的参数,以便于我们设置join buffer的大小,join_buffer_size 此变量的默认大小为256k

有一点需要我们格外注意,不是驱动表中所有的数据都会被加载进join buffer中的,只有被查询的列,所以我们在做查询的时候,不要使用*查询所有的列,要指定要查询的列的字段。

Arduino+L298N电机驱动模块避坑指南:从接线到PWM调速的5个常见错误 本文详细解析了使用Arduino与L298N电机驱动模块时,从电源配置、跳线帽使用到PWM调速的5个常见错误与避坑指南。重点阐述了如何正确分离逻辑与电机电源、拔掉ENA/ENB跳线帽以实现PWM调速、理解H桥接线逻辑以控制直流电机正反转,并提供优化代码与散热建议,帮助开发者稳定驱动电机。 阅读详情

相关推荐

mysql连接原理(搞懂join buf)

概述 一般情况下,我们使用mysql都是使用两种查询比较多,一个是单查询,一个是多连接。多连接原理还是很重要的,特别是对查询优化这块的理解。从空间层面来看,多都不在一个空间,那么可想而知这个是不是更加需要考虑优化,更加需要知道其中的原理原理 1.正常情况下连接 1.两张 stu 和stu_score,也就是一张记录学生基本信息,一张记录学生成绩 2.现在需要join 两张,假设 on 条件为 stu.id=stu_score.stu_id作为连接条件 3.基于stu作为驱

weixin_38312719的博客 1422

Mysql连接join查询原理知识点

Mysql连接(join)查询 1、基本概念 将两个的每一行,以“两两横向对接”的方式,所得到的所有行的结果。 假设: A有n1行,m1列; B有n2行,m2列; 则A和B“对接”之后,就会有: n1*n2行; m1+m2列。 2、则他们对接(连接)之后的结果类似这样: 3、连接查询基本形式: from  1  【连接方式】 join  2  【on连接条件】连接查询基本形式: from  1  【连接方式】 join  2  【on连接条件】 1、连接查询的分类 交叉连接 其实就是两个之间按连接的基本概念,进行连接之后所得到的“所有数据”,而对此无任何“筛选”的结

ARM嵌入式体系结构与接口技术CortexA9版习题答案.pdf

ARM嵌入式体系结构与接口技术CortexA9版习题答案.pdf

mysql连接原理

从本质上来说,连接就是把各个中的数据取出来进行依次匹配的过程。例如,把t1和t2两个连接起来的过程就像下图这样:这个过程看起来就是把t1的记录和t2的记录连起来组成新的更大的记录,所以这个查询过程称之为连接查询。连接查询的结果集中包含一个中的每一条记录与另一个中的每一条记录相互匹配的组合,像这样的结果 集就可以称之为笛卡尔积。如果我们乐意,我们可以连接任意数量张,但是如果没有任何限制条件的话,这些连接起来产生的笛卡尔积可能是非常巨大的。

qq_41534540的博客 1142

一文带你了解MySQL连接原理

连接的本质就是把各个连接中的记录都取出来依次匹配的组合加⼊结果集并返回给用户

Multis 4414

Mysql算法内部算法 - 嵌套循环连接算法

Mysql算法内部算法 - 嵌套循环连接算法1.循环连接算法// 循环连接算法分为两种 1.嵌套循环连接算法 2.块嵌套循环连接算法2.嵌套循环连接算法一个简单的嵌套循环连接(NLJ)算法从一个循环中的第一个中读取一行中的行,将每行传递给嵌套循环,以处理连接中的下一个。该过程重复多次,因为还有待连接。 假设三个之间的连接 t1,t2以及 t3,那么NLJ算法会这么来执行:// 规则 Ta

简简单单Onlinezuozuo 8787

面试之前,MySQL连接必须过关!——连接原理

什么是连接查询?笛卡尔积如何避免?内连接和外连接的概念是什么?连接原理是什么?Simple Nested-Loop Join、Index Nested-Loop Join、 Block Nested-Loop Join、Hash Join分别是什么概念?怎样分析连接使用了哪种连接算法?本文带你一探究竟!

卓越无关环境,保持空杯心态——靡不有初,鲜克有终 6万+

mysql连接原理

一 3种连接 1 内连接 语法: SELECT * FROM t1 JOIN t2 ON t1.m1 = t2.m2; 等价语法: SELECT * FROM t1, t2 where t1.m1 = t2.m2; 内连接会把关联的两个的结果集是他们的交集,两个都可以作为驱动。 2 左连接 语法: SELECT * FROM t1 LEFT JOIN t2 ON t1.m1 ...

weixin_44655181的博客 763

MySQL连接原理

对驱动进行查询时就相当于单查询,也可以通过索引去优化查询速度,当确定了驱动的查询结果时,其实被驱动的查询条件也就确定了,也可以通过加索引去优化查询速度,当然索引是否生效还要看和全扫描的执行效率进行对比。

qq_45795794的博客 1293

MySQL进阶】多连接原理

MySQL进阶】多连接原理

blblccc 2176

Mysql 连接原理

Mysql 连接原理 搞后端的肯定要经常接触到数据库,搞数据库一个避免不了的地方就是 join, join的语法很简单,但是在使用时常常陷入一下两种误区: 误区一: 业务至上,管他三七二十一,再复杂的查询一个连接语句搞定 误区二: 敬而远之,上次写的慢查询sql就是使用了join导致的,以后再也不敢用了 先来举个栗子: mysql> SELECT * FROM t1; +------...

只有变秃 才能变强 1864

MySQL连接原理

首先无论是内连接还是外连接,都会有驱动和被驱动两种,如果是内连接,那么确定第一个需要查询的,这个就是驱动,例如SELECT * FROM t1 INNER JOIN t2 ON t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < ‘d’;而ON在外连接中,如果在被连接中无法匹配到ON子句中的过滤条件的记录时,被连接的记录依然会以NULL的形式加入到结果集中。但是在内连接中,ON与WHERE的作用相同,不符合他们子句中的过滤条件时,都不会被加入到最后的结果集中。

weixin_35856285的博客 607

11. mysql两个连接原理

我们成功建立了t1t2两个,这两个都有两个列,一个是INT类型的,一个是CHAR(1)| 1 | a || 2 | b || 3 | c || 2 | b || 3 | c || 4 | d |连接的本质就是把各个连接中的记录都取出来依次匹配的组合加入结果集并返回给用户。所以我们把t1和t2两个连接起来的过程如下图所示:这个过程看起来就是把t1的记录和t2的记录连起来组成新的更大的记录,所以这个查询过程称之为连接查询。

运维老生常谈 1034

MySQL连接深度解析:原理、类型、算法与优化

mysql连接解析

qq_43460315的博客 1866

MySQL连接查询原理

关系型数据库中至关重要的一点就是Join(连接)。接下来说一下连接原理,首先介绍一下语法。 连接简介 先创建几张: 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’); 从本质上来说:连接就是把各个中的记录取出来按照要求匹配

戳一下有机会获得一份额外加个蛋的蛋炒饭 958

[MYSQL]多连接原理

连接的方式 //from t1, t2 where . . . SELECT * FROM t1, t2 WHERE t1.m = t2.m and . . .; //(inner) join t2 on . . . SELECT column_name(s) FROM t1 INNER JOIN t2 ON t1.m = t2.m and t1.m = 2 . . .; //left join t2 on . . . SELECT column_name(s) FROM t1 LEFT JO

weixin_40775703的博客 1185

mysql 连接解释,[MYSQL]多连接原理

[MYSQL]多连接原理[MYSQL]多连接原理连接的方式//from t1, t2 where . . .SELECT * FROMt1, t2WHERE t1.m = t2.m and . . .;//(inner) join t2 on . . .SELECT column_name(s) FROM t1INNER JOIN t2ON t1.m = t2.m and t1.m =...

weixin_32537985的博客 483

MySQL查询核心:一文吃透 MySQL连接、左连接、右连接原理与实战区别

本文深入解析MySQL连接的三种核心方式:内连接(INNER JOIN)、左连接(LEFT JOIN)和右连接(RIGHT JOIN)。通过创建用户和订单模拟真实业务场景,详细演示了每种连接的具体SQL实现和查询结果差异。内连接只返回两匹配的数据,左连接保留左全部数据并补NULL,右连接保留右全部数据但可被左连接替代。文章强调左连接是最常用的业务场景解决方案,建议统一使用左连接规范以提高代码可读性。掌握这三种连接的区别是编写复杂SQL、优化查询和避免数据统计问题的关键技能,也是SQL面试的重点

xiaoye220911的博客 360

读书笔记之 MySQL 两个连接原理

读书笔记之 MySQL 两个连接原理 文章目录读书笔记之 MySQL 两个连接原理连接笛卡尔积内连接与外连接连接原理嵌套循环连接使用索引加快连接速度索引加速索引覆盖减少回基于块的嵌套循环连接总结 本篇是《MySQL是怎样运行的》第11章 两个的亲密接触 -- 连接原理读书笔记,这里做一些记录和汇总,方便日后复习。 上一篇介绍了单查询的一些访问方法,如果连查询时怎么分析呢? 连接 把多个的记录连起来组成一个更大的新的记录,这个查询过程就是连接查询。 笛卡尔积 如果连接查询的结果集包含一

gxy_2016的博客 936

Mysql连接原理

嵌套循环连接(Netsted-Loop Join) 对于两连接,驱动只会被访问一遍,但是被驱动却要访问好多遍,具体访问几遍取决于对驱动执行单查询后的结果集中的记录条数。对于内连接,选取哪个为驱动都没关系,而外连接的驱动是固定的,也就是说左外连接的驱动就是左边的那个,而右外连接的驱动就是右边那个。 两连接的大致过程: 选取驱动,使用与驱动相关的过滤条件,选取代价最低的单访问方法来执行对驱动的单查询。 对上一步中查询驱动得到的结果集中每一条记录都被分别到被驱动中查找匹配.

mashaokang1314的博客 902
上一篇: 【Mysql】初探表连接的原理
下一篇: 【链表】反转指定区间的链表
LLLDa_&
LLLDa_& 新星创作者: Java技术领域 新星创作者: Java技术领域
博客等级 码龄10年 8535粉丝 · 183原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LLLDa_&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值