用exists代替in真的好么?

Posted 诺浅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用exists代替in真的好么?相关的知识,希望对你有一定的参考价值。

前言

在面试谈到sql优化的一些经验时,有些面试者会回答:写sql时,最好用exists来代替in,因为in不走索引,所以用exists的sql性能较好,那真的是这样么?

以下用AB两表,做个示例,两表都有一个id字段,而两个表都为id字段建立了索引

In

in的作用其实就是把范围内存在的数据做个返回,先看看下图的简单示例sql:

select * from A where id in (select id from B)

这句sql等价于两个循环:

for select id from B
for select * from A where A.id = B.id

其实就是对B表的id做个外层循环,而内层再嵌套一层A表的id循环,内层循环里判断A表和B表的id是否相等,相等的话就是要返回的数据。

Exists

exists的作用就是把主查询的数据,放到自查询中做条件的验证,结果是true则保留主查询中的结果,为false则不保留,以下用exists实现和in一样的效果:

select * from A where exists(select * from B where B.id = A.id)

这句sql也等价于两个循环:

for select * from A
for select * from B where B.id = A.id

其实就是对A表的id做个外层循环,而内层再嵌套一层B表的id循环,内层循环里判断B表和A表的id是否相等,相等的话就是要返回的数据。

这时引申出一个sql优化的规则:以小表驱动大表,mysql连接数会更少,sql性能会更佳

分析下,用in时,是in里面的表驱动外面的表,所以如果B表相对于A表是小表,用in比较好。而用exists时,是外面的表驱动exists里面的表,所以如果A表相对于B表是小表,则用exists比较好。

总结

明白了INEXISTS的原理后,配合上小表驱动大表的优化规则,可以得出用EXISTS或者是用IN,还需要根据表中数据情况而定。

IN适合于外表大而内表小的情况,而EXISTS适合于外表小而内表大的情况。

况且大多数时候是没法用EXISTS来替换IN的,比如如下语句

select * from user where id in(1,2,3)

这句语句有没有多表连接,就不适合用EXISTS,而且坊间盛传的IN不走索引,其实也是不对的,详情见: 不要再问我 in,exists 走不走索引了

以上是关于用exists代替in真的好么?的主要内容,如果未能解决你的问题,请参考以下文章

用exists代替in真的好么?

用exists代替in真的好么?

INEXISTS的相关子查询用INNER JOIN 代替--性能优化

SQL优化--使用 EXISTS 代替 IN 和 inner join来选择正确的执行计划

[MySQL]使用EXISTS代替IN

关于sql中in 和 exists 的效率问题,in真的效率低吗