参考https://www.jianshu.com/p/f212527d76ff

关于exist

EXISTS(包括 NOT EXISTS )子句的返回值是一个boolean值。 EXISTS内部有一个子查询语句(SELECT ... FROM...),我将其称为EXIST的内查询语句。其内查询语句返回一个结果集, EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。

in和exist的查询过程

in和exist分别对应两种查询方式:

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

in相当于一个双重循环,对于A表中的每一个值都要去跟B表中的值进行比较,直到找到匹配的,复杂度为O(nn);
exist只需要对A表进行遍历,对于每一条记录,用哈希索引的方法对B表中进行查询,复杂度为O(n1);

in的查询方式如下:

List resultSet={};
Array A=(select * from A);
Array B=(select id from B);

for(int i=0;i<A.length;i++) {
  for(int j=0;j<B.length;j++) {
      if(A[i].id==B[j].id) {
        resultSet.add(A[i]);
        break;
      }
  }
}
return resultSet;

exist的查询方式如下:

List resultSet={};
Array A=(select * from A);

for(int i=0;i<A.length;i++) {
   if(exists(A[i].id) {  //执行select 1 from B where B.id=A.id是否有记录返回,复杂度为O(1)
       resultSet.add(A[i]);
   }
}
return resultSet;

in和exist的适用情形

当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次
当B表比A表数据大时适合使用exists(),因为它没有那么多遍历操作,只需要再执行一次查询就行。
当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用。