MySQL:如果用left join的话,左边的表一定是驱动表吗

news2024/9/17 4:18:14

一、前言

  在日常开发过程中关于MySQL的优化方面,我们知道小表驱动大表原理。例如left join,放在左边的表作为驱动表。但是用left join的话,左边的表一定是驱动表吗,本文将通过案例分析给出详细分析。

二、概念

  在MySQL中,JOIN操作涉及到两个或多个表的连接,其中一个表被称为驱动表(也称为外表),另一个表或多个表被称为被驱动表(也称为内表或从表)。

  驱动表(外表):在JOIN操作中,首先被访问的表称为驱动表。

  被驱动表(内表或从表):在JOIN操作中,与驱动表进行匹配的表称为被驱动表。

三、优化策略(小表驱动大表原理)

  在MySQL的JOIN操作中,当涉及到两个或多个表的连接时,其中一个表被选为驱动表(小表),另一个表作为被驱动表(大表)。小表驱动大表的原理就是尽量让数据量较小的表作为驱动表,通过其数据去匹配大数据量的表,以减少循环匹配的次数,从而提高查询性能。

示例:
  假设我们有两个表A和B,其中A表有1000行数据,B表有100万行数据。如果以A表作为驱动表去连接B表,那么最多只需要循环1000次;而如果以B表作为驱动表去连接A表,则需要循环100万次。显然,选择A表作为驱动表将大大提高查询性能。

选择小表作为驱动表的好处:

  减少循环次数:当驱动表的数据量较小时,循环的次数会相应减少,从而减少了整体的计算量。反之,如果大表作为驱动表,则需要多次循环遍历大表的数据去匹配小表,这将大大增加计算量。

  利用索引:如果小表上有合适的索引,MySQL可以更快地定位到需要的数据行,进一步减少扫描的行数。同时,索引的使用也可以提高JOIN操作的效率。

  优化器决策:MySQL的优化器会根据表的统计信息、索引情况、查询条件等因素来自动选择最佳的驱动表。优化器的目标是找到一种执行计划,使得查询的代价(如I/O操作、CPU时间等)最小。

四、案例分析

  我们在编写SQL的时候,通常情况下是这样子的
  LEFT JOIN:在左连接中,左边的表通常作为驱动表。
  RIGHT JOIN:在右连接中,右边的表作为驱动表。
  INNER JOIN:对于内连接,MySQL会自动选择数据量较小的表作为驱动表。

这是通常情况下,下面我们准备一些测试数据:

1. 准备数据:

a1表
在这里插入图片描述
a2表
在这里插入图片描述

2.准备查询语句1和查询语句2

语句1
select * from a1 left join a2 on(a1.f1=a2.f1) and (a1.f2=a2.f2); 

语句2
select* from a1 left join a2 on(a1.f1=a2.f1)where (a1.f2=a2.f2);

3. 查询语句1的执行结果
在这里插入图片描述

4. 查询语句2的执行结果
在这里插入图片描述

5. 语句1的EXPLAIN执行结果分析
在这里插入图片描述
从EXPLAIN执行计划中看的出来

  驱动表是表a1,被驱动表是表a2。

  由于表a2的f1字段上没有索引,所以使用的是 Block Nested Loop Join(简称 BNL) 算法。

BNL算法基本原理

  将外层循环的结果集存入join buffer:在BNL算法中,外层循环(通常是较小的表或结果集)的行或结果集会被存储在一个称为join buffer的内存区域中。

  内层循环与buffer中的记录做比较:内层循环(通常是较大的表或结果集)的每一行数据会与整个buffer中的记录进行比较,而不是像传统的Nested Loop Join(NLJ)算法那样,每次只与外层循环的一行进行比较。

结合算法与执行计划语句1的执行过程如下:

  ①. 把表a1的内容读入join_buffer 中

  ②. 顺序扫描表a2,对于每一行数据,判断条件(a1.f1=a2.f1) and (a1.f2=a2.f2)是否满足,满足条件的记录, 作为结果集的一行返回。如果语句中有 where 子句,需要先判断 where 部分满足条件后,再返回。

  ③. 表a2扫描完成后,对于没有被匹配的表a1的行,把剩余字段补上 NULL,再放入结果集中。

6. 语句2的EXPLAIN执行结果分析
在这里插入图片描述
从EXPLAIN执行计划中看的出来

  以表a2为驱动表的。

语句2的执行过程
  顺序扫描表a2,每一行用a2.f1到表a1中去查,匹配到记录后判断a1.f2=a2.f2 是否满足,满足条件的话就作为结果集的一部分返回。

为什么呢,我们执行一下show warnings;看看优化器是怎么做的。
语句1
在这里插入图片描述

语句2
在这里插入图片描述

  在 MySQL 里,NULL 跟任何值执行等值判断和不等值判断的结果,都是 NULL。这里包括, select NULL = NULL 的结果,也是返回 NULL。

  因此,语句2里面 where a1.f2=a2.f2 就表示,查询结果里面不会包含 a2.f2是NULL的行,这样这个left join的语义就是“找到这两个表里面,f1、f2 对应相同的行。

  对于表a1中存在,而表a2中匹配不到的行,就放弃。这样,这条语句虽然用的是 left join,但是语义跟 join 是一致的。

  因此,优化器就把这条语句的 left join 改写成了 join,然后因为表 a1 的 f1 上有索引,就把表 a2 作为驱动表。

五、结论

1、即使我们在SQL语句中写成left join,执行过程还是有可能不是从左到右连接的。也就是说,使用left join时,左边的表不一定是驱动表。

2、如果需要left join的语义,就不能把被驱动表的字段放在where条件里面做等值判断或不等值判断,必须都写在on里面。

六、总结

通过对案例的分析,我们在写sql的时候,就有了优化方案:

1. 用小结果集驱动大结果集,减少外层循环的数据量

2. 如果小结果集和大结果集连接的列都是索引列,mysql在join时也会选择用小结果集驱动大结果集,因为索引查询的成本是比较固定的,这时候外层的循环越少,join的速度便越快。

3. 为匹配的条件增加索引:争取使用Index Nested-Loop Join,减少内层表的循环次数

4. 增大join buffer size的大小:当使用Block Nested-Loop Join时,一次缓存的数据越多,那么外层表循环的次数就越少,减少不必要的字段查询。

5. 当用到Block Nested-Loop Join时,字段越少,join buffer 所缓存的数据就越多,外层表的循环次数就越少。

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

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

相关文章

初识C++ · 模拟实现vector

目录 前言: 1 部分简单函数的实现 2 push_back和pop_back 3 reserve和resize 4 Print_vector 5 insert和erase 6 拷贝构造 7 构造 8 赋值 9 memcpy的问题 10 迭代器失效 前言: 继上文模拟实现了string之后,接着就模拟实现vector&…

Java三种方法实现多线程,继承Thread类,实现Runnable接口,实现Callable接口

目录 线程: 继承Thread类: 实现Runnable类: 实现Callable接口: 验证多线程: 线程: 定义:进程可以同时执行多个任务,每个任务就是线程。举个例子:一个Java程序&#…

rfid资产管理系统如何帮助医院管理耗材的

RFID资产管理系统可以帮助医院管理耗材,提高耗材管理的效率和准确性。以下是它可以发挥作用的几个方面: 1. 实时跟踪和定位:使用RFID标签附加在耗材上,可以实时跟踪和定位耗材的位置。医院可以通过系统查询耗材的实时位置&#xf…

以梦为马,不负韶华(3)-AGI在企业服务的应用

AGI在企业服务中,各应⽤已覆盖企业全流程,包含⼈⼒、法务、财税、流程⾃动化、知识管理和软件开发各领域。 由于⼤语⾔模型对⽂本处理类场景有着天然且直接的适配性,⽂本总结、⽂本内容⽣成、服务指引等发展起步早且应⽤成熟度更⾼。 在数据…

景源畅信电商:做抖店的成本高吗?

在当今数字化时代,抖音不仅仅是一个分享短视频的平台,更是一个充满商机的市场。随着抖音用户量的激增,越来越多的商家和个人开始关注在抖音上开设店铺,即所谓的“抖店”。那么,做抖店的成本高吗?这个问题困扰着许多初…

南京“十元手冲咖啡” :流量怎么砸中你?

三包速溶咖啡、一个塑料热水壶,却意外打造出一款爆品。 南京“十元手冲咖啡”突然爆火,起初靠的是出人意料,你以为她要从罐子里擓粉了,她掏出来三条雀巢速溶;你以为她要用机器打水了,她拿出来一个上世纪的…

鸿蒙开发接口UI界面:【@ohos.mediaquery (媒体查询)】

媒体查询 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 : gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 导入模块 import mediaquery from ohos.media…

微信聊天记录删除了怎么恢复?5个数据恢复方法要收好!

“我删除了手机上的微信,然后我的聊天记录就全没了。我怎样才能恢复以前的微信聊天记录?”作为苹果手机和安卓手机上最流行的即时信息应用程序之一,微信凭借其令人惊叹的功能,目前已拥有超过10亿活跃用户进行交流。只要您的手机上…

堆结构知识点复习——玩转堆结构

前言:堆算是一种相对简单的数据结构, 本篇文章将详细的讲解堆中的知识点, 包括那些我们第一次学习堆的时候容易忽略的内容, 本篇文章会作为重点详细提到。 本篇内容适合已经学完C语言数组和函数部分的友友们观看。 目录 什么是堆 建堆算法…

【CTF Web】CTFShow web2 Writeup(SQL注入+PHP+UNION注入)

web2 1 管理员赶紧修补了漏洞&#xff0c;这下应该没问题了吧&#xff1f; 解法 注意到&#xff1a; <!-- flag in id 1000 -->但是 or 被拦截了。 if(preg_match("/or|\/i",$id)){die("id error");}使用UNION注入&#xff1a; ?id1 union sele…

【鱼眼镜头11】Kannala-Brandt模型和Scaramuzza多项式模型区别,哪个更好?

Kannala-Brandt模型和Scaramuzza多项式模型在描述鱼眼相机畸变时都有其特定的数学表示和应用&#xff0c;但它们之间存在一些区别。以下是对两者区别的分点表示和归纳&#xff1a; 数学表示&#xff1a; Kannala-Brandt模型&#xff1a;它假设图像光心到投影点的距离和角度的多…

Excel某列中有不连续的数据,怎么提取数据到新的列?

这里演示使用高级筛选的例子&#xff1a; 1.设置筛选条件 在D2单元格输入公式&#xff1a;COUNTA(A4)>0 这里有两个注意事项&#xff1a; *. 公式是设置在D2单元格&#xff0c;D1单元格保持为空&#xff0c; **. 为什么公式中选A4单元格&#xff0c;A列的第一个数据在A3…

OpenBayes 教程上新 |全球首个开源的文生视频 DiT 模型!对标 Sora,保姆级 Latte 文生视频使用指南

小朋友不爱背诗怎么办&#xff1f;《千秋诗颂》试试看。 2 月 26 日&#xff0c;中国首部文生视频 AI 系列动画《千秋诗颂》于 CCTV-1 频道正式播出&#xff0c;这部动画由上海人工智能实验室和「央妈」&#xff08;中央广播电视总台&#xff09;强强联手&#xff0c;借助「央视…

什么样的数据摆渡设备,可以满足不同网间数据的安全传输需求?

数据摆渡设备是用来在不同的网络环境间安全地传输数据的硬件或软件解决方案。它们通常用于确保在具有不同安全级别的网络&#xff08;如内网和外网&#xff09;之间进行数据交换时的安全性和合规性。以下是一些常见的数据摆渡设备和方法&#xff1a; 移动介质拷贝&#xff1a;使…

“不是我兄弟”!刘强东内部“狼性训话”流出!

今天&#xff0c;京东创始人刘强东5月24日的线上讲话流出。 在这次线上讲话中&#xff0c;刘强东首先宣布为全体采销员工涨薪20%—100%&#xff0c;随后进行了一番“狼性训话”。往期报道可戳&#xff1a;刘强东怒了&#xff1a;“不是我兄弟”&#xff01; 刘强东在讲话中指…

不同厂商SOC芯片在视频记录仪领域的应用

不同SoC公司芯片在不同产品上的应用信息&#xff1a; 大唐半导体 芯片型号: LC1860C (主控) LC1160 (PMU)产品应用: 红米2A (399元)大疆晓Spark技术规格: 28nm工艺&#xff0c;4个ARM Cortex-A7处理器&#xff0c;1.5GHz主频&#xff0c;2核MaliT628 GPU&#xff0c;1300万像…

初学C语言100题:经典例题节选(源码分享)

1.打印Hello World! #include <stdio.h>int main() {printf("hello world\n");//使用printf库函数 注意引用头文件return 0; } 2.输入半径 计算圆的面积 int main() {float r, s;//定义变量scanf("%f", &r);//输入半径s 3.14 * r * r;// 圆的…

YOLOv8+PyQt5面部表情检测系统完整资源集合(yolov8模型,从图像、视频和摄像头三种路径识别检测,包含登陆页面、注册页面和检测页面)

1.资源包含可视化的面部表情检测系统&#xff0c;基于最新的YOLOv8训练的面部表情检测模型&#xff0c;和基于PyQt5制作的可视化面部表情检测系统&#xff0c;包含登陆页面、注册页面和检测页面&#xff0c;该系统可自动检测和识别图片或视频当中出现的八类面部表情&#xff1a…

Android跨进程通信--Binder机制及AIDL是什么?

文章目录 Binder机制Binder是什么&#xff1f;Binder相对于其他几种跨进程通信方式&#xff0c;有什么区别&#xff1f;谈一下 Binder IPC 通信过程&#xff1a;具体的通讯过程是什么&#xff1f;Binder如何处理发送请求与接收请求?Binder是通过什么方式来进行内存映射的&…

[SWPUCTF 2021 新生赛]pop

常见的魔术方法 魔术方法__construct() 类的构造函数&#xff0c;在对象实例化时调用 __destruct() 类的析构函数&#xff0c;在对象被销毁时被调用 __call() 在对象中调用一个不可访问的对象时被调用&#xff0c;比如一个对象被调用时&#xff0c;里面没有程序想调用的属性 …