数据实测告诉你:不要人云亦云的瞎说EXISTS 与 in 的区别

69 篇文章 2 订阅
订阅专栏
28 篇文章 0 订阅
订阅专栏
博主通过实验对比了MySQL 5.7和8.0版本中IN与EXISTS子查询的性能,发现在5.7版本中,IN通常比EXISTS快,但在8.0版本中,两者性能接近。测试结果显示,8.0版本对EXISTS的优化显著,且整体查询效率优于5.7。结论建议如果可能的话,升级到MySQL 8.0以获得更好的查询性能。
摘要由CSDN通过智能技术生成

背景

实践过程中发现了MySQL一些慢查询,主要出现在in关键字上,查阅相关资料,众多博客都在分析in和 EXISTS 的区别与各自的适用场景,很多都是如下一般,直接给出结论,却没有数据支撑的。

谬论一

 他们的结论言之凿凿的说:

in()适合B表比A表数据小的情况

exists()适合B表比A表数据大的情况
 

谬论二

谬论三


我在实测过程中发现,在5.7环境下,无论是大表驱动小表,还是小表驱动大表,in的速度都优于exists,这不由得让我产生了怀疑。

环境准备

安装两个版本的数据库各一个,一个5.7版本,是阿里云的云数据库,在线测试库,一个8.0版本,安装在本地

数据准备

两个版本的数据库同一份数据,

小表是用户表,有id和userID为索引

-- ----------------------------
-- Table structure for t_cmp_user
-- ----------------------------
DROP TABLE IF EXISTS `t_cmp_user`;
CREATE TABLE `t_cmp_user`  (
  `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `userName` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名称',
  `age` int NULL DEFAULT NULL,
  `gender` int NULL DEFAULT NULL COMMENT '性别1男0女',
  `deptID` int NULL DEFAULT NULL,
  `deptName` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `color` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`, `userID`) USING BTREE,
  INDEX `companyId`(`companyId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 71617 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

大表是操作日志表,otpID和操作人optorID建了索引

-- ----------------------------
-- Table structure for t_cmp_mission_optlog
-- ----------------------------
DROP TABLE IF EXISTS `t_cmp_mission_optlog`;
CREATE TABLE `t_cmp_mission_optlog`  (
  `otpID` bigint NOT NULL AUTO_INCREMENT COMMENT '操作流水id',
  `missionID` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '原子任务id',
  `optorID` int NOT NULL COMMENT '操作人id',
  `optorName` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作人名称',
  `optTm` varchar(21) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作时间',
  `optDesc` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '操作描述',
  `category` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '2' COMMENT '0查阅  1评论  2 操作  3 提醒 默认2',
  `companyId` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  PRIMARY KEY (`otpID`, `optorID`) USING BTREE,
  INDEX `category`(`category`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1627613 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

小表7万+条数据,大表78万+条数据,大表数据量是小表的十倍+

测试过程

小表 in 大表 

小表 in 大表 EXPLAIN 分析结果,5.7与8.0没有区别

EXPLAIN SELECT
	* 
FROM
	`t_cmp_mission_optlog` AS a 
WHERE
	EXISTS (
	SELECT
		userID 
	FROM
		`t_cmp_user` AS b 
	WHERE
	a.optorID = b.userID)

在5.7版本,小表 in 大表执行需要0.959秒,查询结果集1958条

 在8.0版本,同样是查询结果集1958条,执行只需要0.522秒,

大表 in 小表

EXPLAIN SELECT
	* 
FROM
	`t_cmp_mission_optlog` 
WHERE
	optorID IN ( SELECT userID FROM `t_cmp_user` );

大表 in 小表 EXPLAIN 分析结果,5.7与8.0也几乎没有区别

 在5.7版本,大表 in 小表,查询时间15.22秒,结果集78万+条。

  在8.0版本中,大表 in 小表,结果集同样是78万+条。查询时间只需要6.3秒

大表 EXISTS小表

EXPLAIN SELECT
	* 
FROM
	`t_cmp_mission_optlog` AS a 
WHERE
	EXISTS (
	SELECT
		userID 
	FROM
		`t_cmp_user` AS b 
	WHERE
	a.optorID = b.userID)

可以看到8.0使用了索引,而5.7索引失效

而在执行层面,5.7版本的EXISTS效率低到不可忍受,大表EXISTS小表情况下,十几分钟都没出结果

8.0版本7.8秒就查出了78万+条数据,性能与in相差不大

小表 EXISTS大表

EXPLAIN SELECT
	* 
FROM
	`t_cmp_user` AS a 
WHERE
	EXISTS ( SELECT 1 FROM `t_cmp_mission_optlog` AS b WHERE a.userID = b.optorID );

在EXISTS 方面,可以看到8.0使用了索引,而5.7索引失效

在小表EXISTS大表方面,5.7也是拉胯,数据迟迟查不出来

在小表EXISTS大表方面,8.0更是碾压5.7,2000条数据0.5秒就出来了,与in结果相差无几,考虑到误差几乎就是一模一样。

我们可以看到,8.0 EXISTS 与 in 的sql 分析结果是相同的

最后看一下全部sql分析对比

结论

1、网络上那些没有数据支撑的,就乱评论小表驱动大表,大表驱动小表的言论都是错误的

2、在5.7版本中,无论大表在前还是小表在前,in 的查询效率都要远远高于exists 

3、在8.0版本中,得益于版本的改善,in 的查询效率 与 exists 几乎没有明显差别

4、通过对比发现,5.7版本中 exists 不会走索引,而 in  可以走索引。

5、mysql 8 确实比老的5.7效率要高很多,如果有条件,建议升级8.0

如果有小伙伴想重复上述测试,可以找我要数据。

mysql exists效率低_MYSQLexists 语句执行效率变低
weixin_30677191的博客
01-19 1331
在ORACLE 中,我们常常推荐使用exists 来替代in,往往也能取得比较好的优化效果。在ORACLE应用迁往MYSQL的过程中,我们发现部分in 的子查询语句带到MYSQL中,其执行效率变得非常低下,这很让人觉得匪夷所思。于是,我分析了一波。对两个表,分别是一大一小进行关联查询:mysql>selectcount(*)fromusers;+----------+|count(...
T-SQL 之 IN和EXISTS区别和性能比较
qq_38567182的博客
01-21 472
T-SQL 之 IN和EXISTS区别和性能比较
exists与in比较
hzp666的博客
06-17 553
SQL中EXISTS的用法 比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHERE EXISTS( SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID) 这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是.
Java开发者!和字节跳动大佬的技术面谈,实战篇
04-15 146
前言 假如你去面试,面试官让你聊一下对索引的理解,然而你对索引的理解仅限于,检索数据就是快,是一种数据结构这个层面,那你就只能回家等通知了。 为了避免这种尴尬的事情发生,咔咔用时两天将索引的内容在自己理解的范围内进行了整理,如有整理不全面的地方可以在评论区进行补充和提建议。 一:开源框架、底层源码分析 学习Java技术体系,设计模式,流行的框架与组件 常见的设计模式,编码必备 Spring5,做应用必不可少的最新框架 MyBatis,玩数据库必不可少的组件 二:分布式架构 高并发,高可用,海量数据,没
mysql的in与excit_干货|mysql:exists还是in?哪个性能好?为什么?
weixin_33773734的博客
01-18 596
作者:wanber来源:牛客网在项目中经常会用到in和exists,他们功能几乎一样,那么性能有什么差别呢?性能分析说明:SELECT * FROM A WHERE id IN (SELECT id FROM B);外表指A,子表指Bin 是把外表和子表作hash 连接,而exists是对外表作loop循环,每次loop循环再对子表进行查询。1、in语句:SELECT * FROM A WHERE...
mySQL中in查询与exists查询的区别小结
09-09
MySQL中的`IN`查询和`EXISTS`查询都是在处理子查询时常用的操作,它们各自有不同的特性和适用场景。理解两者的区别对于优化SQL查询性能至关重要。 ### `IN`查询 `IN`查询通常用于检查某列的值是否在特定的值列表中...
sql语句优化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的语句
09-14
SQL语句优化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的语句 SQL语句优化是数据库性能优化的重要方面之一。在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS...
MySQL exists 和in 详解及区别
09-09
### `EXISTS`与`IN`的区别 1. **性能**:在某些情况下,`EXISTS`可能比`IN`更快,尤其是当子查询返回大量数据时。`EXISTS`通常可以更早地停止执行,而`IN`可能需要扫描整个结果集。 2. **返回值**:`EXISTS`仅检查...
INEXISTS与NOT INNOT EXISTS 的优化原则小结
12-15
在SQL查询优化中,`IN`、`EXISTS`、`NOT IN`和`NOT EXISTS`是四个常见的比较和过滤条件,它们在不同场景下有不同的性能表现。以下是对这些操作符优化原则的详细说明: 1. **EXISTS的执行流程**: `EXISTS` 子查询...
sql not in 与not exists使用中的细微差别
12-15
这些细小的差别千万不要被我们所忽视,一旦项目庞大了,想跟踪到具体的错误所花费的时间也是可观的。尽量把这些不必要的错误扼杀在摇篮里。 啰嗦了,呵呵。 上面两个简单的Sql,我们从表面理解,查询的最终结果应该...
IN和EXISTS区别和使用
weixin_41979002的博客
07-14 3万+
SQL中IN和EXISTS用法的区别 结论 in()适合子表比主表数据小的情况 exists()适合子表比主表数据大的情况 当主表数据与子表数据一样大时,in与exists效率差不多,可任选一个使用. 使用IN的情况 select * from A where id in(select id from B) 以上查询A为主表,B为子表;使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍
SQL难点对比分析:IN 和 EXISTS 的用法对比
Robin_Pi的博客
04-23 3424
SQL难点对比分析:IN 和 EXISTS 的用法对比
Mysql中in和exists区别 & not in、not exists、left join的相互转换
最新发布
心流时间的博客
09-09 4311
Mysql中in和exists区别 & not in、not exists、left join的相互转换
MySQL中In与Exists区别
热门推荐
Lzc的博客
06-17 3万+
MySQL中In与Exists区别1 例子2 EXISTS和IN的介绍2.1 exists2.2 in2.3 使用上的区别3 EXISTS和IN的性能分析总结 1 例子 有两个表需要关联查询,表的情况如下: # 2759174行数据 SELECT COUNT(*) FROM tb_data t1; # 7262行数据 SELECT COUNT(*) FROM tb_task t2; # 执行...
EXISTS和IN的区别
weixin_70280523的博客
07-18 6661
条件
MySQL5.7和8.0中in和exists关键字
czx2018的博客
07-11 1788
之前看了网上很多关于in和exists性能相关的博客,但总感觉自己测试的结果和他们说的不太一样,所以写下这篇博客,记录下自己测试后得出的总结。特别强调,MySQL5.7和8.0中对这两个关键字有不同的优化,所以我要分开两个版本来讨论。 数据准备 我准备了一张tb_class表和一张tb_stu表 注:600个班级,12万个学生。tb_stu是大表,tb_class是小表。为了避免索引优化带来的影响,所以我两张表的id都没有设置主键和索引。 MySQL5.7测试 测试查询效率 我们首先测试一下当外层表时小
达梦数据库培训笔记
weixin_55910426的博客
07-15 1995
达梦数据库培训笔记
exists和in的区别
木头
02-08 9351
A:In:是把外表和内表做Hash 连接,而exists 是对外表作loop 循环,每次loop循环再对内表进行查询。 当查询两个表的大小相当时,用In 和 exists差别不大。 如果两个表中一个表较小,一个表较大,那么子查询表大的用exists,子查询表小的用In,效率会高的。 也就是说IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况,这样效率会高的 例如 :表a(小表),表b(大表) 1.select * fromawhere aid in (select ai...
Exists与in的区别(简介)
weixin_48743471的博客
11-21 1040
适用范围:功能区别:原理区别
写文章

热门文章

  • MyBatis-Plus 批量插入 146699
  • 下载并安装windows版本的Redis 123028
  • redis客户端连接(error) NOAUTH Authentication required 111194
  • 找寻一款redis数据库可视化工具(RedisDesktopManager) 94516
  • curl命令模拟json格式的post请求 85073

分类专栏

  • elasticsearc 1篇
  • nacos 1篇
  • 算法 3篇
  • dubbo 2篇
  • kafka 1篇
  • java8新特性 4篇
  • Java虚拟机规范阅读笔记 7篇
  • 图数据库 1篇
  • 洞悉中外,布局未来 9篇
  • java框架 86篇
  • Struts2 3篇
  • web下载 1篇
  • java文件下载 3篇
  • dom4j解析xml 1篇
  • java读取xm文件 1篇
  • 配置文件 28篇
  • properties 1篇
  • Linux 32篇
  • 阿里云连接 3篇
  • 云服务器 20篇
  • Hibernate 27篇
  • jar包下载 4篇
  • oracle 10篇
  • IED使用 14篇
  • MysQL 28篇
  • SSH 60篇
  • Java基础 81篇
  • 面试题 69篇
  • 线程锁 7篇
  • 随笔 10篇
  • Spring 62篇
  • java模式 7篇
  • 工具 78篇
  • AspectJ 6篇
  • maven 3篇
  • html5 1篇
  • mybatis 46篇
  • springmvc 10篇
  • python 3篇
  • jquer 1篇
  • redis 20篇
  • jetty 5篇
  • nginx 6篇
  • https 1篇
  • spring-boot 40篇
  • vue-js 13篇
  • starring 3篇
  • docker 2篇
  • mongodb 4篇
  • mycat 4篇
  • rabbitmq 13篇
  • zookeeper 1篇
  • git 3篇
  • IntelliJ IDEA 4篇
  • ftp 1篇
  • Jooq 1篇
  • 微信二次开发 3篇

最新评论

  • Spring Boot中文文档

    圣心: 这个中文翻译也挺好 https://spring-doc.cadn.net.cn/spring-boot/3.3.2-SNAPSHOT/index.html

  • 记一次failed to req API:/nacos/v1/ns/instance after all servers([127.0.0.1:8848]) tried:ConnectE解决过程

    qq_47686912: 配置都是对的,搞了半天都不行,重启一下结果就可以了,为什么会有这种事情啊

  • 数据实测告诉你:不要人云亦云的瞎说EXISTS 与 in 的区别

    小姚_: 楼主发一份数据,想测一下,感谢

  • 记一次failed to req API:/nacos/v1/ns/instance after all servers([127.0.0.1:8848]) tried:ConnectE解决过程

    手可摘月亮: 哈哈 感谢你啊

  • 数据实测告诉你:不要人云亦云的瞎说EXISTS 与 in 的区别

    要身心健康: 但是我有个sql就是用in很慢,用exists快了很多,感觉很玄学

大家在看

  • C# 加载外部EXE程序,并触发程序中的按钮
  • 用AI制作美女跳舞视频!猛涨粉23w!只需3步就能学会
  • 应对flashcenterlibcrypto-1_1.dll缺失问题的快速解决指南 457
  • 《堡垒之夜》emp.dll丢失怎么办,找不到emp.dll的解决策略 824
  • ArkTS 如何适配手机和平板,展示不同的 Tabs 页签 81

最新文章

  • spring扩展之基于HandlerMapping实现接口灰度发布的demo
  • 实现了Spring的Aware接口的自定义类什么时候执行的?
  • springboot自定义starter实践
2022年45篇
2021年19篇
2020年45篇
2019年58篇
2018年54篇
2017年270篇

目录

目录

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家清远景观雕塑玻璃钢河北玻璃钢花盆玻璃钢鹿雕塑价格常州做玻璃钢雕塑吉安人物玻璃钢雕塑晋城铸铜玻璃钢卡通雕塑厂家三亚玻璃钢雕塑厂家福州人物玻璃钢雕塑生产厂家迪庆玻璃钢雕塑厂家直销成都特色玻璃钢雕塑订做价格蚂蚁玻璃钢卡通雕塑定制铜陵户外玻璃钢雕塑蜗牛玻璃钢卡通雕塑订做玻璃钢仿真水果雕塑公司涪陵玻璃钢仿铜雕塑湛江玻璃钢雕塑销售价格上海动物玻璃钢雕塑销售厂家天津花钵玻璃钢雕塑厂家邯郸玻璃钢人物玻璃钢雕塑吉林水果玻璃钢雕塑生产厂家濮阳玻璃钢室外雕塑定做厂家玉溪玻璃钢马雕塑天水仿真玻璃钢雕塑安装芜湖美陈商场布置大型主题商场美陈生产企业玻璃钢雕塑仿真树贵州环保玻璃钢雕塑价位招远玻璃钢关公雕塑天使玻璃钢雕塑张家界动物玻璃钢雕塑价格香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化