Mysql中in和exists的区别 not in、not exists、left join的相互转换

news2024/11/26 4:26:50

文章目录

  • 1. in 介绍
    • 1.1 in中数据量的限制
    • 1.2 null值不参与in或not in,也就是说in and not in 并不是全量值,排除了null值
    • 1.3 in的执行逻辑
  • 2. exists介绍
    • 2.1 exists + not exists 是全量数据
    • 2.2 exists的执行逻辑
  • 3. 小表驱动大表的好处
  • 4. in、not in、exists、not exists是否可以走索引(都可以)
  • 5. not in、 not exists、left join语句相互转换(必须在表关联时,否则并不等同)
    • 5.1 not in
    • 5.2 not exists
    • 5.3 left join + is null

数据准备

-- 建表
CREATE TABLE `xin_stu_t_bak` (
  `id` bigint NOT NULL COMMENT '主键',
  `relation_id` bigint DEFAULT NULL COMMENT '外键, 记录教师id',
  `student_name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `student_age` bigint DEFAULT NULL COMMENT '年龄',
  `school` varchar(300) DEFAULT NULL COMMENT '学校',
  KEY `relationid` (`relation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xin_teach_t_bak` (
  `id` bigint NOT NULL COMMENT '主键',
  `teacher_name` varchar(30) DEFAULT NULL COMMENT '教师姓名',
  `teacher_age` bigint DEFAULT NULL COMMENT '教师年龄',
  `school` varchar(300) DEFAULT NULL COMMENT '学校',
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- 加索引
create index id on xin_stu_t_bak(relation_id);
create index id on xin_teach_t_bak(id);

-- 添数据
INSERT INTO lelele.xin_stu_t_bak (id,relation_id,student_name,student_age,school) VALUES
	 (1,NULL,'尤仁义1',11,'徐州中学'),
	 (2,1,'尤仁义2',12,'徐州中学'),
	 (3,NULL,'朱有理1',11,'徐州中学'),
	 (4,2,'朱有理2',12,'徐州中学'),
	 (5,2,'朱有理3',13,'徐州中学'),
	 (6,3,'宋昆明1',11,'徐州中学'),
	 (7,3,'宋昆明2',12,'徐州中学'),
	 (8,14,'宋昆明3',13,'徐州中学');

INSERT INTO lelele.xin_teach_t_bak (id,teacher_name,teacher_age,school) VALUES
	 (1,'王翠花1',31,'徐州中学'),
	 (2,'王翠花2',31,'徐州中学'),
	 (3,'王翠花3',33,'徐州中学'),
	 (4,'王翠花4',34,'徐州中学'),
	 (5,'王翠花5',35,'徐州中学'),
	 (1,'王翠花1',31,'徐州中学'),
	 (1,'王翠花1',31,'徐州中学'),
	 (2,'王翠花2',31,'徐州中学'),
	 (6,'王翠花6',31,'徐州中学'),
	 (7,'王翠花7',31,'徐州中学');
INSERT INTO lelele.xin_teach_t_bak (id,teacher_name,teacher_age,school) VALUES
	 (8,'王翠花8',33,'徐州中学'),
	 (9,'王翠花9',34,'徐州中学'),
	 (10,'王翠花10',35,'徐州中学'),
	 (11,'王翠花11',31,'徐州中学'),
	 (12,'王翠花12',31,'徐州中学'),
	 (13,'王翠花13',31,'徐州中学');

1. in 介绍

1.1 in中数据量的限制

在oracle中,int中数据集的大小超过1000会报错;
在mysql中,超过1000不会报错,但也是有数据量限制的,应该是4mb,但不建议数据集超过1000,
因为in是可以走索引的,但in中数据量过大索引就会失效

1.2 null值不参与in或not in,也就是说in and not in 并不是全量值,排除了null值

select * from xin_stu_t_bak a where a.relation_id in ( select id from xin_teach_t_bak b)

在这里插入图片描述

select * from xin_stu_t_bak a where a.relation_id not in ( select id from xin_teach_t_bak b)

在这里插入图片描述

select * from xin_stu_t_bak a

在这里插入图片描述

从此处可以看出,in和not in 加在一起并不是全量的值,排除了null值


1.3 in的执行逻辑

  1. 当前的in子查询是B表驱动A表
  2. mysql先将B表的数据一把查出来至于内存中
  3. 遍历B表的数据,再去查A表(每次遍历都是一次连接交互,这里会耗资源)
  4. 假设B有100000条记录,A有10条记录,会交互100000次数据库;再假设B有10条记录,A有100000记录,只会发生10次交互。

结论: in是先进行子查询,再与外面的数据进行循环遍历,属于子查询的结果集驱动外面的结果集,
当in子查询的结果集较小时,就形成了小表驱动大表,而两张表的驱动就是一张表的行数据去循环关联另一张表,
关联次数越少越好,所以小表去查询大表,次数更少,性能更高
in()适合B表比A表数据小的情况

2. exists介绍

2.1 exists + not exists 是全量数据

select * from xin_stu_t_bak a where exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

exist + not exists 是全量数据,这点与in不同

2.2 exists的执行逻辑

  1. 当前exists查询是A表驱动B表
  2. 与in不同,exists将A的纪录数查询到内存,因此A表的记录数决定了数据库的交互次数
  3. 假设A有10000条记录,B有10条记录,数据库交互次数为10000;假设A有10条,B有10000条,数据库交互次数为10。

结论:exists理论上就是boolean值,关联后查询到有值则是true数据留下,关联后查询没有值则是false数据舍弃;
exists适合B表数据量大,A表数据量小的情况,与in相反

3. 小表驱动大表的好处

我们来看下面两个循环:

for (int i = 0; i<10000; i++){ 

	for(int j = 0; j<10; j++){
	
	}
}
for (int i = 0; i<10; i++){ 

	for(int j = 0; j<10000; j++){
	
	}
}

在java中,我们都知道上述的两个循环的时间复杂度都是一样的;
但在数据库中则是有区别的,
首先第一层循环,数据库只做一次交互一把将数据查出到缓存中,
而第二层循环的数据库交互次数决定于第一层循环数据量的大小。
对于数据库而言,交互次数越多越耗费资源,一次交互涉及了“连接-查找-断开”这些操作,是相当耗费资源的。
使用in时,B表驱动A
使用exists时,A表驱动B
所以我们写sql时应当遵循“小表驱动大表“的原则

4. in、not in、exists、not exists是否可以走索引(都可以)

in可以走索引,但数据量过大时就不走索引了
not in、exist、not exists也都可以走索引

  • in

select * from xin_stu_t_bak a where a.relation_id in ( select id from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

select * from xin_stu_t_bak a where a.relation_id in (‘1’, ‘2’)

在这里插入图片描述


  • not in

select * from xin_stu_t_bak a where a.relation_id not in (‘1’, ‘2’)

在这里插入图片描述


  • exists

select * from xin_stu_t_bak a where exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述


  • not exists

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

5. not in、 not exists、left join语句相互转换(必须在表关联时,否则并不等同)

5.1 not in

select * from xin_stu_t_bak a where a.relation_id not in ( select id from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

5.2 not exists

select * from xin_stu_t_bak a where not exists ( select 1 from xin_teach_t_bak b where a.relation_id = b.id)

在这里插入图片描述

5.3 left join + is null

select a.* from xin_stu_t_bak a left join xin_teach_t_bak b on a.relation_id = b.id where b.id is null;

在这里插入图片描述

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

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

相关文章

图像噪声--添加噪声

椒盐噪声 椒盐噪声就是给图片添加黑白噪点&#xff0c;椒指的是黑色的噪点(0,0,0),盐指的是白色的噪点(255,255,255)&#xff0c;通过num来控制噪声多少&#xff0c;值越大添加的噪声越多&#xff0c;图像损坏的更加严重。 void add_salt_pepper_noise(Mat& src,Mat& …

Mojo-SDK详细安装教程

Mojo-SDK安装 运行环境&#xff1a;windows11wsl2&#xff08;ubuntu1804&#xff09; 截至20230909&#xff0c;windows,mac系统暂时不支持 step1: Install VS Code, the WSL extension, and the Mojo extension. step2: Install Ubuntu 22.04 for WSL and open it. step…

Vue el-table 重置按钮设计模板

vue 文件演示模板 <template><el-button icon"el-icon-refresh" size"large" click"resetFunction">重置</el-button><el-tableheight"450"v-loading"loading":data"dataList":row-key&quo…

U盘插上就让格式化是坏了吗?数据怎么恢复

U盘插上就让格式化是坏了吗&#xff1f;当您遇到U盘插上后提示需要格式化的情况时&#xff0c;不要慌张。这种情况并不一定意味着U盘已经坏了。下面我们一起来了解下如何恢复里面的数据&#xff0c;并解决U盘提示格式化的问题。 U盘一插上就提示格式化是什么原因 许多人可能会有…

个人微信多账号聚合管理如何实现?

在日常工作中&#xff0c;您是否会遇到以下问题&#xff1a; 微信号多&#xff0c;需反复切换设备及账号&#xff0c;工作效率低。 无法快速响应客户消息&#xff0c;客户体验感差。 无法随时掌握员工与客户沟通情况&#xff0c;员工沟通质量难以控制&#xff0c;管理难。 员…

Spring系列文章:面向切面编程AOP

一、代理模式 1、代理模式使用场景引入 ⽣活场景1&#xff1a;⽜村的⽜⼆看上了隔壁村⼩花&#xff0c;⽜⼆不好意思直接找⼩花&#xff0c;于是⽜⼆找来了媒婆王妈妈。这 ⾥⾯就有⼀个⾮常典型的代理模式。⽜⼆不能和⼩花直接对接&#xff0c;只能找⼀个中间⼈。其中王妈妈是…

OpenCV 11(图像金字塔)

一、 图像金字塔 **图像金字塔**是图像中多尺度表达的一种&#xff0c;最主要用于图像的分割&#xff0c;是一种以多分辨率来解释图像的有效但概念简单的结构。简单来说, 图像金字塔是同一图像不同分辨率的子图集合. 图像金字塔最初用于机器视觉和图像压缩。其通过梯次向下采…

shell知识点复习

1、shell能做什么&#xff08; Shell可以做任何事(一切取决于业务需求) &#xff09; 自动化批量系统初始化程序 自动化批量软件部署程序 应用管理程序 日志分析处理程序 自动化备份恢复程序 自动化管理程序 自动化信息采集及监控程序 配合Zabbix信息采集 自动化扩容 2、获取当…

淘宝双11数据分析与预测课程案例中(林子雨)错误点总结

问题一&#xff1a;可视化代码中男女买家各个年龄段对比散点图中数值不显示以及坐标不正确问题如下图 解决方法&#xff1a; 1修改坐标 2修改数值 修改后散点图 问题二&#xff1a;各省份的总成交量对比中地图显示不出来 有时间再写

海量小文件传输对于企业选用文件传输软件的重要意义

在当前的商业环境中&#xff0c;数据具有极其重要的作用&#xff0c;是企业竞争的核心要素。随着互联网、物联网和云计算等技术的快速发展&#xff0c;数据的类型和规模变得越来越多样。在这其中&#xff0c;海量小文件作为一种普遍而重要的数据形式&#xff0c;扮演着连接信息…

新知同享 | Mobile 开发轻松跨屏,高效构建

谷歌致力于帮助开发者 更快、更轻松地打造高质量的移动体验 一起来看 2023 Google 开发者大会上 Mobile 开发值得重点关注的成果与更新 了解如何提高平台及应用质量 提升开发效率 使多设备开发体验更流畅 实现轻松跨屏&#xff0c;高效构建 精彩大会现场一览 用户对跨屏幕体验…

在k8s中创建ConfigMap的四种方式与初识helm包管理工具

非敏感数据&#xff0c;比如应用的配置信息&#xff0c;则可以用ConfigMap 创建configmap四种方式 &#xff08;1&#xff09;通过--from-literal&#xff1a; kubectl create configmap myconfigmap --from-literalconfig1xxx --from-literalconfig2yyy 每个--from-literal…

Revit SDK 介绍:Ribbon 界面

前言 Revit 通过 API 将完整的 Ribbon 做了保留&#xff0c;同时这些菜单按钮也可以和相应的命令绑定。 内容 运行效果如下所示&#xff1a; 菜单特写&#xff1a; Ribbon Sample 整体是 API 暴露出来的一个 RibbonPanel&#xff0c;对应的接口&#xff1a; namespace Au…

dll文件反编译源代码 C#反编译 dotpeek反编译dll文件后export

目录 背景下载安装dotpeek导入dll文件export导出文件参考 背景 项目合作的时候&#xff0c;使用前人的或者其他部门dll文件直接在机台运行&#xff0c;会出现很多问题&#xff0c;逻辑&#xff0c;效率等等&#xff0c;此时我们可以选择对他们的代码进行反编译和重构&#xff…

递归算法学习——被围绕的区域,太平洋大西洋流水问题

目录 ​编辑 一&#xff0c;被围绕的区域 1.题意 2.解释 3.题目接口 4.解题思路及代码 二&#xff0c;太平洋大西洋流水问题 1.题意 2.解释 3.题目接口 4.解题思路及代码 一&#xff0c;被围绕的区域 1.题意 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和…

对卷积的一点具象化理解

前言 卷积的公式一般被表示为下式&#xff1a; 对新手来说完全看不懂这是干什么&#xff0c;这个问题需要结合卷积的应用场景来说。 原理 卷积比较广泛的应用是在信号与系统中&#xff0c;所以有些公式的定义会按照信息流的习惯。假设存在一串信号g(x)经过一个响应h(x)时他的响…

高云USB下载器仿真器用户手册(包括在线逻辑分析仪的使用方法)

高云 USB 仿真器用户手册 一.简介 仿真器用于高云 GOWIN 公司所生产的 FPGA&#xff0c;可用于程序下载和调试。主要特点如下&#xff1a; 1.支持宽电压1.2V - 3.6V&#xff1b; 2.速度最高可达30Mb/s&#xff0c;极速完成下载和波形调试功能&#xff1b; 3.完美支持在线逻…

Java实现Modbus读写数据

背景 由于当时项目周期赶&#xff0c;引入了一个PLC4X组件&#xff0c;上手快。接下来就是使用这个组件遇到的一些问题&#xff1a; 关闭连接NioEventLoop没有释放导致oom设计思想是一个设备一个连接&#xff0c;而不是一个网关一个连接连接断开后客户端无从感知 前两个问题解…

什么牌子的电容笔比较好?开学值得买触控笔推荐

大部分学生都没有固定的收入&#xff0c;所以他们选择的商品都是偏向性价比高的。随着iPad的不断升级&#xff0c;它的各种功能也会越来越多&#xff0c;将会慢慢地走进我们的生活和工作中。随着电子设备的不断更新和软件的完善&#xff0c;电容笔的性能也在不断提高&#xff0…

783. 二叉搜索树节点最小距离

783. 二叉搜索树节点最小距离 C代码&#xff1a;二叉树 int min; int pre;int dfs(struct TreeNode* root) {if (root NULL) {return;}dfs(root->left);if (pre ! -1) {min fmin(min, root->val - pre);}pre root->val; // 中序遍历dfs(root->right); }int mi…