俩者执行过程:
IN 执行过程:
sql示例:select * from tabA where x in (select x from tabB);
其执行计划:
(1)执行tabB表的子查询,得到结果集B;
(2)执行tabA表的查询,查询条件是x在结果集B里面,可以使用到tabA表的索引x。
Exists执行过程
sql示例:select * from tabA where exists (select x from tabB where tabA.x = x);
其执行计划:
(1)先将tabA表所有记录取到。
(2)逐行针对tabA表的记录,去关联tabB表,判断tabB表的子查询是否有返回数据,5.5之后的版本使用Block Nested Loop(Block 嵌套循环)。
(3)如果子查询有返回数据,则将tabA当前记录返回到结果集。
tabA相当于取全表数据遍历,tabB可以使用到索引。
个人总结:
当子查询结果集很大,而外部表较小的时候,Exists的Block Nested Loop(Block嵌套循环)的作用开始显现,并弥补外部表无法用到索引的缺陷,查询效率会优于IN。in 相当于把子查询查到的结果放到内存里和外查询比较,当子查询查到的数据过大时效率就低了,而exists相当于子查询是一次又一次的查询数据库。
当子查询结果集较小,而外部表很大的时候,Exists的Block嵌套循环优化效果不明显,IN 的外表索引优势占主要作用,此时IN的查询效率会优于Exists。