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)