大家好,我是神韵,是一个技术&生活博主。出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己。二是希望我的文章可以帮到大家。欢迎来点赞打卡,你们的行动将是我无限的动力。
本篇主题是:MySQL in和exists 查询分析
看到了就简单记录一下,以后忘了可以回来看~
目录
以前一直没使用过exists这个关键字,现在才知道它基本上来说,如果不计数据量大小,其实比in查询还快,下面先介绍in和exists查询原理。
exists原理:
select * from A a
where exists (
select 1 from B b where a.id = b.id
);
- 首先执行外查询select * from A a,然后从外查询的数据取出一条数据传给内查询。
- 内查询执行select * from B b,外查询传入的数据和内查询获得数据根据where后面的条件做匹对,如果存在数据满足a.id=b.id则返回true,如果一条都不满足则返回false。
- 内查询返回true,则外查询的这行数据保留,反之内查询返回false则外查询的这行数据不显示。外查询的所有数据逐行查询匹对。
总结:先查外查询,然后用外查询数据去内查询根据where做匹配,如果存在则保留外查询记录。如果外查询数据量小,内查询数据量大,使用exists效果比in查询高。
not exists和exists的用法相反,就不继续啰嗦了。
in原理:
select * from A
where id in (
select id from B
);
- 首先执行内查询select id from B,然后将查询符合的所有数据的id传给外查询。
- 外查询根据内查询返回的所有id, 执行select * from A where id in查询符合的数据返回。
总结:先查内查询,然后用内查询数据做外查询返回符合记录。如果外查询数据量大,内查询数据量小,并且有索引情况,使用in比exists查询效率高。
not in和in的用法相反,就不继续啰嗦了。
例子:
下面是力扣的一道题目-寻找用户推荐人
这道题有很多解法,我这里介绍用not in和not exists两种解法
not exists解法(同一个表也能用哦~)
select name
from customer c1
where not exists (
select 1 from customer c2 where referee_id = 2 and c1.id = c2.id
);
查询过程:
1、先在外customer c1查询出所有的记录
2、依次将六条记录传入内查询customer c2。
2.1、id=1时,不符合查询条件,结果返回false,not exists识别是false,外层保留记录1
2.2、id=2时,不符合查询条件,结果返回false,not exists识别是false,外层保留记录2
2.3、id=3时,referee_id=2符合查询条件,结果返回true,not exists识别是true,外层跳过不保留记录3
....剩下三条跳过记录6,保留记录4.5
总的就保留了记录12、45,跳过了3、6
3、将保留的所有结果返回
not in
select name
from customer c1
where id not in
(select id from customer c2 where referee_id = 2)
查询过程:
1、先在内customer c2查询出所有符合的记录id=3、6
2、将id=3、6放到外层查询进行查询
查询语句就变成
select name
from customer c1
where id not in (3,6)
3、外查询将过滤掉id为3,6的其它数据返回
总结:
- in和exists执行时,in是先执行内查询,然后再执行外查询。而exists查询它是先执行外查询,然后再执行内查询(这里的内外查询不理解可以结合上面的分析理解)。
- exists和in在执行时效率单从执行时间来说差不多,exists要稍微优干in,在使用时一般应该是用exists而不用in。
- 如果内查询得出的结果集记录较少,外查询中的表较大且又有索引时应该用in,反之如果外查询记录较少,内查询中的表大,又有索引时使用exists。
- in只能返回一个字段,exists可以返回多个字段,但是exists返回的是啥是没有任何意义的,通常返回1就行。
上面就是对in和exists的讲解,知识相对比较入门。