Mysql--JOIN连表查询
一、Join查询原理
MySQL内部采用了一种叫做 nested loop join(嵌套循环连接)的算法:通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复,基本上MySQL采用的是最容易理解的算法来实现join
所以驱动表的选择非常重要,驱动表的数据小可以显著降低扫描的行。
一般情况下参与联合查询的两张表都会一大一小,如果是join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表。简单来说,驱动表就是主表,left join 中的左表就是驱动表,right join 中的右表是驱动表。

二、Nested-Loop Join
如 select * from t1 inner join t2 on t1.id=t2.tid ,t1称为外层表,也可称为驱动表,t2称为内层表,也可称为被驱动表
mysql只支持一种join算法:Nested-Loop Join(嵌套循环连接),但Nested-Loop Join有三种变种:
- 简单嵌套循环连接:Simple Nested-Loop Join(SNLJ)
- 索引嵌套循环连接:Index Nested-Loop Join(INLJ)
- 缓存块嵌套循环连接:Block Nested-Loop Join(BNLJ)
在选择Join算法时,会有优先级,理论上会优先判断能否使用INLJ、BNLJ: Index Nested-LoopJoin > Block Nested-Loop Join > Simple Nested-Loop Join
2.1 Simple Nested-Loop Join
如下图,r为驱动表,s为匹配表,可以看到从r中分别取出r1、r2、…、rn去匹配s表的左右列,然后再合并数据,对s表进行了rn次访问,对数据库开销大。
如果table1有1万条数据,table2有1万条数据,那么数据比较的次数=1万 * 1万 =1亿次,这种查询效率会非常慢。
故基本不使用这种方式,mysql会根据情况选择其他两种方式进行查询

2.2 Index Nested-Loop Join(减少内层表数据的匹配次数)
- 索引嵌套循环连接是基于索引进行连接的算法,索引是基于内层表的,通过外层表匹配条件直接与内层表索引进行匹配,避免和内层表的每条记录进行比较, 从而利用索引的查询减少了对内层表的匹配次数,优势极大的提升了 join的性能
- 使用场景:只有内层表join的列有索引时,才能用到Index Nested-LoopJoin进行连接
- 由于用到索引,如果索引是辅助索引而且返回的数据还包括内层表的其他数据,则会回内层表查询数据,多了一些IO操作
这个要求非驱动表(匹配表s)上有索引,可以通过索引来减少比较,加速查询。
在查询时,驱动表(r)会根据关联字段的索引进行查找,当在索引上找到符合的值,再回表进行查询,也就是只有当匹配到索引以后才会进行回表查询。
如果非驱动表(s)的关联健是主键的话,性能会非常高,如果不是主键,要进行多次回表查询,先关联索引,然后根据二级索引的主键ID进行回表操作,性能上比索引是主键要慢。

2.3 Block Nested-Loop Join(减少内层表数据的循环次数)
缓存块嵌套循环连接通过一次性缓存多条数据,把参与查询的列缓存到Join Buffer 里,然后拿join buffer里的数据批量与内层表的数据进行匹配,从而减少了内层循环的次数(遍历一次内层表就可以批量匹配一次Join Buffer里面的外层表数据)。
当不使用Index Nested-Loop Join的时候(内层表查询不适用索引),默认使用Block Nested-Loop Join
- Join Buffer会缓存所有参与查询的列而不是只有Join的列
- 可以通过调整join_buffer_size缓存大小
- join_buffer_size的默认值是256K,join_buffer_size的最大值在MySQL 5.1.22版本前是4G-1,而之后的版本才能在64位操作系统下申请大于4G的Join Buffer空间
- 使用Block Nested-Loop Join算法需要开启优化器管理配置的optimizer_switch的设置block_nested_loop为on,默认为开启

三 优化
- 用小结果集驱动大结果集,减少外层循环的数据量:如果小结果集和大结果集连接的列都是索引列,mysql在内连接时也会选择用小结果集驱动大结果集,因为索引查询的成本是比较固定的,这时候外层的循环越少,join的速度便越快
- 为匹配的条件增加索引:争取使用INLJ,减少内层表的循环次数
- 增大join buffer size的大小:当使用BNLJ时,一次缓存的数据越多,那么外层表循环的次数就越少
- 减少不必要的字段查询:
- 当用到BNLJ时,字段越少,join buffer 所缓存的数据就越多,外层表的循环次数就越少
- 当用到INLJ时,如果可以不回表查询,即利用到覆盖索引,则可能可以提示速度
- 尽量使用inner join,避免left join 和NULL
摘抄自(有删改):https://blog.csdn.net/agonie201218/article/details/106993948
四 补充
4.1 找出所有在左表,不在右表的纪录
注:列值为null应该用is null 而不能用=NULL
a.user_id 列必须声明为 NOT NULL 的
select id, name, action from user as u left join user_action a on u.id = a.user_id where a.user_id is NULL
4.2 where使用
在连表查询时,通常在子查询中使用 WHERE 子句限制表数据会比在最后的主查询中使用 WHERE 子句效率更高。
原因是,在子查询中使用 WHERE 子句可以对较小的结果集进行过滤,减少了主查询需要处理的数据量。这样可以减少数据的传输和处理的负担,提高查询性能。
另一方面,在最后的主查询中使用 WHERE 子句时,会先执行联接操作并获取所有的匹配行,然后再对整个结果集进行过滤。这样会导致在查询过程中处理了更多的数据,增加了查询的开销,可能导致性能下降。
因此,将限制条件放在子查询中,可以尽早地过滤数据,只将需要的数据传递到后续的查询阶段,减少了不必要的计算和数据传输,更加高效。
SELECT A.*
FROM 大表A A
JOIN (SELECT * FROM 小表B WHERE C) AS B ON A.关联键 = B.关联键;
4.2 多表联合查询
在MySQL关联查询中,建议将小表作为驱动表,而将大表作为被驱动表。
因为小表通常拥有较少的记录,而大表可能包含大量的数据。当小表作为驱动表时,MySQL可以先从小表中获取数据,并使用这些数据来查询大表。这样做的好处是可以减少查询的数据量,提高查询的效率。如果将大表作为驱动表,MySQL需要先扫描大表的所有记录,然后再根据关联条件查询小表,这样会增加查询的时间和资源消耗。
需要注意的是,选择驱动表的原则是根据查询的条件和数据量来决定,而不是根据表的大小。有时候大表可能也是更适合作为驱动表的,这需要根据具体的情况进行分析和测试。
假设t4为大表:
select
b.name,
c.view_name,
a.notify_time,
a.product,
a.alarm_id
from
(
select
psa,
group_id
from
t1
) a
left join (
select
id,
name
from
t2
) b on a.group_id=b.id
left join (
select
view_name,
psas
from
t3
where
type='alarm'
) c on concat('"', c.psas, '"') regexp a.psa
left join (
select
notify_time,
product,
alarm_id
from
t4
where
product!='/'
) d on d.product=b.psa
Mysql--JOIN连表查询的更多相关文章
- MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...
- day15(mysql 的多表查询,事务)
mysql之多表查询 1.合并结果集 作用:合并结果集就是把两个select语句查询的结果连接到一起! /*创建表t1*/ CREATE TABLE t1( a INT PRIMARY KEY , b ...
- mysql数据库优化课程---11、mysql普通多表查询
mysql数据库优化课程---11.mysql普通多表查询 一.总结 一句话总结:select user.username,user.age,class.name,class.ctime from u ...
- Mariadb/MySQL数据库单表查询基本操作及DML语句
Mariadb/MySQL数据库单表查询基本操作及DML语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一数据库及表相关概述 1>.数据库操作 创建数据库: CREATE ...
- day 39 MySQL之多表查询
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都 ...
- MySQL的联表查询
MySQL的联表查询 首选:分析查询的字段来自哪些表 进而:确定交集 然后:确定判断的条件 比如:从student表 和 result表 查学号.考试名称.学时.考试日期.考试成绩 表1: 学号 考试 ...
- 对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。
对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引. 问题: 大量的left join 怎么优化 select a.id,a.num,b.num,b.pcs,c.num, c. ...
- Vc数据库编程基础MySql数据库的表查询功能
Vc数据库编程基础MySql数据库的表查询功能 一丶简介 不管是任何数据库.都会有查询功能.而且是很重要的功能.上一讲知识简单的讲解了表的查询所有. 那么这次我们需要掌握的则是. 1.使用select ...
- mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱
mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱 前言:使用 mybatis generator 生成表格对应的pojo.dao.mapper,以及对应的example的 ...
- MySQL之单表查询 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER BY 八 限制查询的记录数:LIMIT 九 使用正则表达式查询
MySQL之单表查询 阅读目录 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER B ...
随机推荐
- .Net8 Blazor 尝鲜
全栈 Web UI 随着 .NET 8 的发布,Blazor 已成为全堆栈 Web UI 框架,可用于开发在组件或页面级别呈现内容的应用,其中包含: 用于生成静态 HTML 的静态服务器呈现. 使用 ...
- [ORB/BEBLID] 利用OpenCV(C++)实现尺度不变性与角度不变性的特征找图算法
本文只发布于利用OpenCV实现尺度不变性与角度不变性的特征找图算法和知乎 一般来说,利用OpenCV实现找图功能,用的比较多的是模板匹配(matchTemplate).笔者比较喜欢里面的NCC算法. ...
- 手撕Vue-Router-初始化路由信息
前言 经过上一节课的学习,我们已经完成了提取我们想要的路由信息数据格式,提取完毕了之后,接下来我们该干什么,接下来需要做的步骤就是监听路由的变化,保存当前的路由. 那么就会遇到几个问题,就是怎么监听, ...
- TCP传输层详解(计算机网络复习)
介绍:TCP/IP包含了一系列的协议,也叫TCP/IP协议族,简称TCP/IP.该协议族提供了点对点的连接机制,并将传输数据帧的封装.寻址.传输.路由以及接收方式都予以标准化 TCP/IP的分层模型 ...
- [QOJ1359] Setting Maps
题目链接 \(k=1\) 的时候显然是最小割.把一个点 \(u\) 拆成 两个点,中间连流量为 \(c_u\) 的边. 那么考虑扩展到 \(k\) 更大的情况.把上图的每个入点和出点都拆成 \(k\) ...
- [UOJ#748] [UNR#6 1B] 机器人表演
在这个科技发达的年代,真人表演已经落伍了.参加完 UOI 后,hehe 蚤去到了下山市大剧院,观看下山市最火爆的机器人表演. 机器人有时比人类更能抓住事情的本质.所谓表演,其实也就是开场有若干个机器人 ...
- smm整合
配置整合 这个里面SpringConfig 就是书写Spring的配置类,其中加载了jdbc配置类和mybatis配置类,还加载了jdbc资源类. package com.itheima.config ...
- 为什么要实践 A+ES & CQRS ?
Wow : 基于 DDD & EventSourcing 的现代响应式 CQRS 架构微服务开发框架 中文文档 领域驱动 | 事件驱动 | 测试驱动 | 声明式设计 | 响应式编程 | 命令查 ...
- MinIO客户端之mb
MinIO提供了一个命令行程序mc用于协助用户完成日常的维护.管理类工作. 官方资料 mc mb MinIO对象锁定 桶版本控制 桶复制 站点复制概述 创建桶bkt1,命令如下: ./mc mb lo ...
- 国家专用加密数据传输之rsa,3des加密方法-rasor3desc
title: 国家专用加密数据传输之rsa,3des加密方法 date: 2021-12-20 13:08:21.646 updated: 2022-03-10 16:00:58.65 url: ht ...