使用的数据库如下:
in语句:常用于where表达式中,其作用是查询某个范围内的数据,只执行一次。
SELECT * FROM city WHERE pid IN(SELECT pid FROM province WHERE city.`pid` =1);
SELECT * FROM A WHERE id IN(SELECT id FROM B);
等价于:1、SELECT id FROM B----->先执行in中的查询
2、SELECT *FROM A WHERE A.id = B.id
执行结果:
以上语句执行流程:
首先会执行in()中的语句,即先执行in里面的子查询,然后在将查询到的结果和user表做一个笛卡尔积,在根据id in (1,2,3...16)来对结果进行筛选,最后得到符合条件的数据。
exists: exists()指定一个子查询,返回的是一个bool值,并不会返回任何数据。
SELECT * FROM city WHERE EXISTS (SELECT pid FROM province WHERE city.`pid` =1 );
SELECT * FROM a WHERE EXISTS (SELECT * FROM b WHERE B.id= A.id);
以上查询等价于:
1、SELECT * FROM A;
2、SELECT * FROM B WHERE B.id= A.id;
执行结果和上面的一样。
执行流程:
首先执行的是主查询,也就是说先执行的sql语句是:SELECT * FROM city,执行的结果是全部的city表中的信息,然后在去执行EXISTS (SELECT pid FROM province WHERE city.pid = 1);中的语句,如果成立的话,就返回true,则该行结果保留,返回false的话,该结果就不保留。
区别:
in使用于子查询得出的结果集较少,主查询较大的情况,反之如果外层的主查询记录较少,子查询中的结果集较大则应该用exists。
in是把外表和内表做hash连接,而exists是对外表做loop循环,每次loop循环在对内部进行查询。
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
注意:
SELECT * FROM city WHERE EXISTS (SELECT * FROM city LIMIT 0);//会返回city中的全部结果,等效于 SELECT * FROM city 因为exists查询的本质,只要碰到有记录,则返回true;所以limit根本就不会去管,或者说执行不到。