select * from A where id in(select id from B)
结论:in () 适合 B 表比 A 表数据小的情况
select a.* from A a where exists(select 1 from B b where a.id=b.id)
EXISTS 用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值 True 或 False。 EXISTS 指定一个子查询,检测 行 的存在。
结论:exists () 适合 B 表比 A 表数据大的情况
区别及应用场景
in 和 exists 的区别:如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用 in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用 exists。其实我们区分 in 和 exists 主要是造成了驱动顺序的改变 (这是性能变化的关键),如果是 exists,那么以外层表为驱动表,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外 IN 时不对 NULL 进行处理。
not in 和 not exists
如果查询语句使用了 not in 那么内外表都进行全表扫描,没有用到索引;而 not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用 not exists 都比 not in 要快。
EXISTS 与 IN 的使用效率的问题,通常情况下采用 exists 要比 in 效率高,因为 IN 不走索引,但要看实际情况具体使用: IN 适合于外表大而内表小的情况;EXISTS 适合于外表小而内表大的情况。