exists

sql语句中的exists查询的用法,以及与in子查询的性能比较。

资源

正文

理解

可以理解为:
for x in ( select * from t1 )
loop
   if ( exists ( select null from t2 where y = x.x )
   then
      OUTPUT THE RECORD!
   end if
end loop

——这个更容易理解,t1永远是个表扫描!因此t1绝对不能是个大表,而t2可以很大,因为y=x.x可以走t2.y的索引。

EXISTS运算符的含义为”存在”,即用于从一个数据集中查询在另一个数据集(子查询)中存在的数据记录。使用 EXISTS 关键字引入一个子查询时,就相当于进行一次存在测试。外部查询的 WHERE 子句测试子查询返回的行是否存在。子查询实际上不产生任何数据;它只返回 TRUE 或 FALSE 值

示例

deploy_id在f5_application表中存在,但是在f5_info不存在的的情况。主查询是f5_application。由于使用了exists查询,所以,必须要用别名。即f5_application.deploy_id 不能省略表。

子查询中主要返回true、false两种情况,所以

SELECT * FROM `f5_application` WHERE not EXISTS (SELECT `deploy_id` FROM f5_info where deploy_id = f5_application.deploy_id ) 
 

-- SELECT DISTINCT deploy_id FROM f5_application WHERE deploy_id is not null 


-- SELECT DISTINCT deploy_id  from f5_info where deploy_id is not null 

-- 简化理解如下
-- select * from A where exists(select cc from B where cc=A.cc)

比较in exists

结论: 综合以上对IN/EXISTS的讨论,我们可以得出一个基本通用的结论:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

另外一个差别,是结果上的差别。因为F5_info表里面,存在deploy_id 为空的情况。发现sql1结果为空。sql2才是正常的结果。不知道为啥。

-- sql1
SELECT * FROM `f5_application` WHERE `deploy_id` NOT IN (SELECT `deploy_id` FROM `f5_info`   )
-- sql2
SELECT * FROM `f5_application` WHERE `deploy_id` NOT IN (SELECT `deploy_id` FROM `f5_info` is not null)