EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
要点一:执行顺序
EXISTS语法:
SELECT 字段 FROM table WHERE EXISTS (subquery);
subquery是一个受限的SELECT语句(不允许有COMPUTE子句和INTO关键字)
示例:
SELECT * FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.user_id = A.id);
(1)首先执行一次外部查询,并缓存结果集,如 SELECT * FROM A
(2)遍历外部查询结果集的每一行记录R,代入子查询中作为条件进行查询,如 SELECT 1 FROM B WHERE B.id = A.id
(3)如果子查询有返回结果,则EXISTS子句返回TRUE,这一行R可作为外部查询的结果行,否则不能作为结果
要点二: 等价关系
下面三种情况返回数据相同,都会返回student表的所有数据:
select * from student;
select * from student where exists (select 1);
select * from student where exists (select null);
对user表的记录逐条取出,由于子查询中的select 1永远能返回记录行,那么student表的所有记录都将被加入结果集
要点三: EXISTS与NOT EXISTS相反
总的来说,如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件,二者意思相反,用法类似
要点四: IN和EXISTS
(1)IN和NOT IN常用于where表达式中,其作用是查询某个范围内的数据。 (2)IN和NOT IN语句分别可以用EXISTS和NOT EXISTS 进行改写 (3)EXISTS某些情况下可以比IN提高运行效率; 而用NOT EXISTS都比NOT IN要快 (4)如果两个表中一个较小,一个是大表, 则建议子查询表大的用exists,子查询表小的用in 例如:表A(小表),表B(大表) 示例一:
select * from A where cc in (select cc from B)
select * from A where exists(select cc from B where cc=A.cc)
【注意】
此时子查询为表B(大表),用exists效率高。
示例二
select * from B where cc in (select cc from A)
select * from B where exists(select cc from A where cc=B.cc)
【注意】
此时子查询为表A(小表),用IN效率高。
要点五:NOT IN和NOT EXISTS
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。
所以无论那个表大,用NOT EXISTS都比NOT IN要快。
|