SQL中的EXISTS子句和IN子句有什么区别?

什么时候应该使用EXISTS,什么时候应该使用IN?


当前回答

IN只支持平等关系(或前面有NOT的不平等关系)。 它是=any / =some的同义词

select    * 
from      t1 
where     x in (select x from t2)
;

EXISTS支持不能用IN表示的不同类型的关系,例如-

select    * 
from      t1 
where     exists (select    null 
                  from      t2 
                  where     t2.x=t1.x 
                        and t2.y>t1.y 
                        and t2.z like '℅' || t1.z || '℅'
                  )
;

还有另一种说法——

exist和IN之间所谓的性能和技术差异可能是由于特定供应商的实现/限制/错误造成的,但很多时候它们只是由于缺乏对数据库内部结构的理解而产生的神话。

表的定义、统计数据的准确性、数据库配置和优化器的版本都会影响执行计划,因此也会影响性能指标。

其他回答

原因是EXISTS操作符基于“至少找到”原则。它返回true,一旦找到至少一个匹配的行,就停止扫描表。

另一方面,当IN操作符与子查询结合时,MySQL必须先处理子查询,然后使用子查询的结果来处理整个查询。

一般的经验法则是,如果子查询包含一个较大的 对于大量的数据,EXISTS操作符提供了更好的性能。 但是,如果使用IN操作符,查询将执行得更快 子查询返回的结果集非常小。

不同之处在于:

select * 
from abcTable
where exists (select null)

上面的查询将返回所有记录,而下面的查询将返回空。

select *
from abcTable
where abcTable_ID in (select null)

尝试一下并观察输出。

我的理解是,只要我们不处理NULL值,两者都应该是相同的。

同样的原因,查询不返回值for = NULL vs is NULL。 http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

至于布尔和comparator参数,为了生成一个布尔值,两个值都需要进行比较,这就是任何if条件的工作方式。所以我不明白IN和EXISTS的行为有什么不同 .

EXISTS is much faster than IN when the subquery results is very large. IN is faster than EXISTS when the subquery results is very small. CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT) GO CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20)) GO INSERT INTO t1 SELECT 1, 'title 1', 5 UNION ALL SELECT 2, 'title 2', 5 UNION ALL SELECT 3, 'title 3', 5 UNION ALL SELECT 4, 'title 4', 5 UNION ALL SELECT null, 'title 5', 5 UNION ALL SELECT null, 'title 6', 5 INSERT INTO t2 SELECT 1, 1, 'data 1' UNION ALL SELECT 2, 1, 'data 2' UNION ALL SELECT 3, 2, 'data 3' UNION ALL SELECT 4, 3, 'data 4' UNION ALL SELECT 5, 3, 'data 5' UNION ALL SELECT 6, 3, 'data 6' UNION ALL SELECT 7, 4, 'data 7' UNION ALL SELECT 8, null, 'data 8' UNION ALL SELECT 9, 6, 'data 9' UNION ALL SELECT 10, 6, 'data 10' UNION ALL SELECT 11, 8, 'data 11' Query 1 SELECT FROM t1 WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id) Query 2 SELECT t1.* FROM t1 WHERE t1.id not in (SELECT t2.t1id FROM t2 ) If in t1 your id has null value then Query 1 will find them, but Query 2 cant find null parameters. I mean IN can't compare anything with null, so it has no result for null, but EXISTS can compare everything with null.

我发现使用EXISTS关键字通常非常慢(这在Microsoft Access中非常真实)。 相反,我以这样的方式使用join操作符: should-i-use-the-keyword-exists-in-sql