MySQL关键字OR/IN/NOT IN/EXISTS/NOT EXISTS的区别

本文深入探讨了SQL查询中IN、OR、EXISTS和NOT EXISTS子句的性能差异。在有索引的情况下,IN和OR的性能相似,但在无索引时,OR的性能随数据量增加显著下降。EXISTS优于IN,特别是当子查询表较大时。NOTIN和NOTEXISTS比较中,NOTEXISTS通常优于NOTIN,尤其在涉及全表扫描时。优化查询性能的关键在于合理利用索引和选择适当的子查询结构。
IN 和 OR 的区别:

如果in和or所在列有索引或者主键的话,or和in没啥差别,执行计划和执行时间都几乎一样。

如果in和or所在列没有 索引的话,性能差别就很大了。在没有索引的情况下,随着in或者or后面的数据量越多,in的效率不会有太大的下降,但是or会随着记录越多的话性能下降 非常厉害。

因此在给in和or的效率下定义的时候,应该再加上一个条件,就是所在的列是否有索引或者是否是主键。如果有索引或者主键性能没啥差别,如果没有索引,性能差别不是一点点!

IN 和 EXISTS 的区别:

EXISTS代表存在量词∃。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或者逻辑假值“false”。

IN是把外表和内表作hash连接;
而EXISTS是对外表进行便利,每次取外表的一条记录去结合内层查询(子查询)结果,若内层查询结果为非空,则外层的WHERE子句返回值为真,否则返回值为假。

如果查询的两个表大小相当,那么用IN和EXISTS差别不大;如果两个表中一个较小一个较大,则子查询表大的用EXISTS,子查询表小的用IN;

例如:表A(小表),表B(大表)

select * from A where cc in(select cc from B);  
--效率低,用到了A表上cc列的索引
select * from A where exists(select cc from B where cc=A.cc);  
--效率高,用到了B表上cc列的索引

相反的:

select * from B where cc in(select cc from A)  
--效率高,用到了B表上cc列的索引
select * from B where exists(select cc from A where cc=B.cc)  
--效率低,用到了A表上cc列的索引

考虑性能的话,就按子表大主表小用EXISTS,子表小主表大用IN的原则就可以

写法的不同,
EXISTS的where条件是: “… where EXISTS (… where a.id=b.id)”
IN的where条件是:" … where id IN ( select id … where a.id=b.id)"

在这里插入图片描述

NOT IN 和NOT EXISTS的区别

如果查询语句使用了NOT IN 那么内外表都进行全表扫描,没有用到索引;
而NOT EXISTS的子查询依然能用到表上的索引;
所以无论那个表大,用NOT EXISTS都比NOT IN要快。

一个简单例子,有两张表。一张用户表,一张订单表(包含有用户ID),需要查询没有下过订单的用户。
在这里插入图片描述
在这里插入图片描述

采用NOT EXISTS和NOT IN分别查出未下过订单的用户

NOT IN 查询SQL语句如下:

SELECT * from ttt_user u WHERE u.user_id not in (SELECT user_id from 
ttt_order o WHERE o.user_id = u.user_id)

NOT IN 查询执行计划如下:
在这里插入图片描述

NOT EXISTS 查询SQL语句如下:

SELECT * from ttt_user u WHERE not EXISTS (SELECT user_id from 
ttt_order o WHERE o.user_id = u.user_id)

NOT EXISTS 查询执行计划如下:
在这里插入图片描述

同时也贴一下IN 和EXISTS的查询计划:

IN 查询执行计划如下:
在这里插入图片描述

EXISTS 查询执行计划如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值