MySQL 外连接和内连接的查询优化怎么做?

news2025/1/21 20:26:52

目录

1. 表连接方式的分类和需要注意的细节

2. 表连接时底层做了什么事?

3. 左外连接优化方案

4. 内连接优化方案


1. 表连接方式的分类和需要注意的细节

多表连接查询,大体上可以分为内连接与外连接

内连接的意思就是把两个表有关联的部分都取出来,不分主表和次表,在连接时从我们的角度来说是不分谁是驱动表谁是被驱动表,但 MySQL 的查询优化器底层会做一个初步计算,计算出谁作为驱动表效率更高;

外连接则又分为左外连接,右外连接,满外连接(全外连接)。左外连接和右外连接中是分主表和此表的,所以本篇文章中点来说左外连接与右外连接的优化策略。

左外连接中左表是主表,也就是驱动表,右表作为从表,也就是被驱动表;语法为"表A LEFT JOIN 表B ON 查询条件";

右外连接中右表是主表,作为驱动表,右表是从表,作为被驱动表;语法为"表A RIGHT JOIN 表B ON 查询条件";

2. 表连接时底层做了什么事?

在没有任何索引的情况下,当两张表在进行连接查询操作的时候,实际上底层做的第一件事就是拿出驱动表一条记录与被驱动表的所有记录去做匹配,看是否满足条件,匹配完毕之后,再拿出驱动表的第二条记录与被驱动表的所有记录去做匹配,看是否有满足条件的记录,以此类推,直到驱动表所有记录均与被驱动表的所有记录进行过匹配并得出了满足条件的结果,两张表的连接查询的第一步连接操作就完成了。大致过程如下图所示

3. 左外连接优化方案

(1)小表驱动大表

通过上面表连接时进行匹配可以看出,两个表在进行连接查询时,驱动次数与驱动表的数据量有关,A表的数据量越少,与B表进行驱动的次数越少,所以第一种优化左外连接的方法就是将数据量小的表作为驱动表,让数据量小的表去与数据量大的表进行匹配,就可以减少驱动次数;

(2)给被驱动表的匹配字段添加索引

如下是 employee 员工表和 department 部门表,部门表的主键 部门id 

SELECT e.employee_id,d.department_id
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;

驱动表与被驱动表进行匹配时,连接条件是 查询条件字段 = 某个值。本例子中就是 员工表中的部门 id = 部门表中的部门 id。

没有给被驱动表的匹配字段添加索引:取出驱动表的一条数据,确定查询字段为 id = 12,那么与被驱动表匹配查询时,就是挨个将被驱动表中的每条数据取出做判断,看被驱动表的 id 是否为12,这其实就是一个全表扫描的过程。假设 employee 表中有20条数据,deparement 部门表中有30条数据,最坏的情况需要匹配 20 * 30 = 600 次,最好的情况是每次取出被驱动表第一条数据恰好能匹配到,只需要匹配20次。

给被驱动表的匹配字段添加了索引:接着刚才的说,如果被驱动表中给 id 字段添加了索引,那么被驱动表就可以精准查找 id = 12 的这条记录是否存在,查询不到则说明没有返回空,这样就不需要对被驱动表做全表扫描,省去了大量的时间。每次驱动只需要在 department 部门被驱动表中进行一次查询,效率得到了很大的提升。

(3) 若有WHERE查询条件,给WHERE查询字段添加索引

假如说在两个表进行了多表连接查询之后,我们还需要进一步的做过滤,一般都会在WHERE中添加过滤条件,此时想要进一步提高SQL的执行效率,就可以给WHERE查询条件的字段上添加索引。如果不加索引就会向上面一样进行一个全表扫描,取出每一条表连接之后的数据与WHERE的查询条件做匹配,加了索引就可以精确判断,迅速过滤掉无用的数据,提高性能。

(4)表连接查询查询条件字段类型一定要保持一致

如果不保持一致,就算我们为被驱动表添加了索引,索引也是失效的,因为数据类型不一致,所以数据库底层就需要全表扫描将每条数据都拿出来,然后先进行数据类型的转换,再去做条件的匹配,因此一定要注意,多表连接查询查询条件的字段类型一定要保持一致,否则会因为隐式类型转换导致索引失效。

4. 内连接优化方案

首先需要明确的一点是,内连接查询表面上是不分主表和此表的,默认来说左边的表就是驱动表,右边的表就是被驱动表。但在执行查询之前,SQL优化器会从和判断查询字段是否存在索引和两张表那个表数据量较少,会选出一个数据量小的作为驱动表,选出查询字段有索引的作为被驱动表。

如下图,是我数据库中的 employee员工表和 department 部门表,

department 部门表中有27条数据,

department_id 是主键,有数据库默认生成的主键索引

 

employee 员工表中有107条数据;

 在 employee 员工表中,我们给 department_id 外键添加普通索引

现在两个表中都有 department_id 的索引, 

如下SQL语句,使用 explain 关键字显示查询计划,我们将 employee 写在坐标作为驱动表,将department 部门表作为被驱动表,看看 employee 会作为驱动表吗

EXPLAIN SELECT e.employee_id,d.department_id
FROM employees e INNER JOIN departments d
ON e.department_id = d.department_id;

可以观察到,虽然SQL语句中将 employee 写在左边作为驱动表,但 explain 执行计划中显示实际执行SQL语句的时候会将 department 作为驱动表,为什么呢?

因为 department 表中只有27条数据,比employee 表的107条数据少得多,能大大减少驱动次数,提高效率,所以内连接查询中,基本上都是哪个数据量少哪个表作为驱动表。

因此在实际开发设计表的时候,如果需要涉及到多表查询,应该尽量在数据量多的表(被驱动表)中经常需要查询的字段上添加索引,可以大大降低表连接查询匹配消耗的时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1165259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树进阶 - (C++二叉搜索树的实现)

二叉树进阶 - (二叉搜索树的实现) 二叉搜索树1. 二叉搜索树概念2. 二叉搜索树操作2.1 二叉搜索树的查找2.2 二叉搜索树的插入2.3 二叉搜索树的删除(重点) 3. 二叉搜索树的(代码)实现 二叉搜索树 1. 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0…

MySQL是如何优化in子查询的?

目录 前言 一、普通in子查询 二、物化表 三、SQL优化 四、IN语句的优化方式 1. 使用子查询代替IN查询 2. 使用JOIN代替IN查询 3. 使用EXISTS代替IN查询 4. 使用索引优化IN查询 5. 优化查询语句 总结 前言 对于很多的开发小伙伴来说,在MySQL中进行in子查…

Antlr4学习笔记

目录 背景 相关概念 流程说明 入门示例 简易计算器 环境准备 开发 java8方法提取 语法规则 常用的语法要点 设计语法 序列模式 选择模式 词法符号依赖 嵌套模式 总结 参考资料 背景 在阅读shardingjdbc-4.1.1代码时,发现一段sql解析的逻辑&#x…

极智开发 | H100服务器的庐山真面目

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文分享一下 H100服务器的庐山真面目。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq H100 是英伟达最强显卡,当然其实也…

stable-diffusion 电商领域prompt测评集合

和GhostReivew一个思路,还是从比较好的图片或者是civitai上找一些热门的prompt,从小红书上也找到了不少的prompt,lexica.art上也有不少,主要是为了电商场景的一些测评: 小红书、civitai、Lexica、Liblib.ai、 depth o…

基于GEE云平台一种快速修复Landsat影像条带色差的方法

这是之前关于去除遥感影像条带的另一篇文章,因为出版商推迟了一年发布,所以让大家久等了。这篇文章的主要目的是对Landsat系列卫星因为条带拼接或者镶嵌产生的条带来进行的一种在线修复方式。 原文连接 一种快速修复Landsat影像条带色差的方法 题目&a…

app开发之后需要做什么

在完成app的开发之后,还有一系列的工作需要进行,以确保app的顺利上线和用户的良好体验。下面将从原理和详细介绍两个方面来介绍app开发之后需要做的工作。 一、原理介绍 1. 测试与调试:在app开发完成后,需要进行全面的测试与调试…

防范欺诈GPT

去年,ChatGPT的发布让全世界都感到惊讶和震惊。 突然间出现了一个平台,它比之前的任何其他技术都更深入地了解互联网。人工智能可以被训练成像阿姆一样说唱,以世界著名诗人的风格写作,并精确地翻译内容,以至于它似乎能…

初识Vue 解决vue在启动时生成的提示

让我为大家简单介绍一下吧&#xff01; Vue是一套用于构建用户界面的渐进式javaScript框架 当我们引入vue.js后 <script src"../js/vue.js"></script>我们发现&#xff0c;当我们打开网页时&#xff0c;控制台会出现以下内容 那我们该怎么解决呢&…

思科网络基础

目录 一、特殊的ip地址 1.一些基本概念 2.私有地址 3.子网划分 4.VLSM&#xff08;可变长子网掩码&#xff09; 5.CIDR&#xff08;无类域间路由-超网&#xff09; 二、IP头和一些基本概念 1.ip头 2.mtu 3.免费arp 一、特殊的ip地址 1.一些基本概念 网络位不变&…

卡尔曼家族从零解剖-(04)贝叶斯滤波→细节讨论,逻辑梳理

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解的 卡尔曼家族从零解剖 链接 :卡尔曼家族从零解剖-(00)目录最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/133846882 文末正下方中心提供了本人 联系…

玩转AIGC:如何选择最佳的Prompt提示词?

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Spring、SpringMVC、Mybatis

一.Spring基础 1.Spring 框架是什么 Spring 是一款开源的轻量级 Java 开发框架&#xff0c;我们一般说 Spring 框架指的都是 Spring Framework&#xff0c;它是很多模块的集合&#xff0c;例如&#xff0c;Spring-core、Spring-JDBC、Spring-MVC 等&#xff0c;使用这些模块可…

Vite 的基本原理,和 webpack 在开发阶段的比较

目录 1&#xff0c;webpack 的流程2&#xff0c;Vite 的流程简单编译 3&#xff0c;总结 主要对比开发阶段。 1&#xff0c;webpack 的流程 开发阶段大致流程&#xff1a;指定一个入口文件&#xff0c;对相关的模块&#xff08;js css img 等&#xff09;先进行打包&#xff0…

【MySql】11- 实践篇(九)

文章目录 1. 大查询是否会把数据库内存打爆?1.1 全表扫描对 server 层的影响1.2 全表扫描对 InnoDB 的影响 2. 可不可以使用join?2.1 Index Nested-Loop Join2.2 Simple Nested-Loop Join2.3 Block Nested-Loop Join 3. join语句怎么优化?3.1 Multi-Range Read 优化3.2 Batc…

安装Oracle 11g Error in invoking target报错

在redhat7.5上安装Oracle 11g&#xff0c;安装过程中到86%时出现Error in invoking target报错 原因是由于操作系统版本过高&#xff0c;导致lib链接报错 [oracleemrtest ~]$ cd O R A C L E H O M E / s y s m a n / l i b / [ o r a c l e e m r t e s t l i b ] ORACLE…

没有PDF密码,如何解密文件?

PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。想要解密&#xff0c;我们需要输入正确的密码&#xff0c;但是有时候我们可能会出现忘记密码的情况&#xff0c;或者网上下载P…

canvas制作电子白板签名功能

Canvas是html5主要的画图工具&#xff0c;用户可以利用js在里面构思自己的创意&#xff0c;页面上很多手写签名是通过这个来完成的&#xff0c;让我们来用一个简单的例子作为抛砖引玉。 效果图 源代码 <html> <head> <meta charset"utf-8"> &l…

【脚本工具】视频抽帧、添加srt字幕朗读、添加背景音频

1.文章目录 看完本文章&#xff0c;你将能学会一下内容&#xff1a; 批量视频抽帧&#xff1b;添加srt字幕&#xff1b;添加srt配音&#xff1b;添加背景音乐&#xff1b;多视频片段合成一个新视频&#xff1b; 效果&#xff1a; 2.安装依赖 首先安装视频处理库opencv-pyth…

ERR invalid password

E:\Document_Redis_Windows\redis-2.4.5-win32-win64\64bit redis.conf