1)用IN
select * from A
where id in(select id from B);
以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来。注意,是缓存了起来。之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录。
可以看出,当B表数据较大时不适合使用 in(),因为它会B表数据全部遍历一次。
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次。
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次。
2)用EXISTS
select a.* from A a
where exists(select 1 from B b where a.id=b.id);
以上查询使用了exists语句,exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false。
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次。
那,两种情况有什么不一样呢?不好意思,在没有where子句的时候,是一样的。因为根本没有筛选条件,何来先后的作用?
看下面一种解释:
in 操作的原理是先进行子查询操作,再进行主查询操作(适合主查询是大表,子查询是小表)。
exists 操作的原理是先进行主查询操作,再到子查询中进行过滤(适合主查询是小表,子查询是大表)。
但是,我更喜欢使用 in,因为更便于语句的改写,语义也更加明确。