SQL中的EXISTS子句和IN子句有什么区别?
什么时候应该使用EXISTS,什么时候应该使用IN?
SQL中的EXISTS子句和IN子句有什么区别?
什么时候应该使用EXISTS,什么时候应该使用IN?
当前回答
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.
其他回答
不同之处在于:
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关键字通常非常慢(这在Microsoft Access中非常真实)。 相反,我以这样的方式使用join操作符: should-i-use-the-keyword-exists-in-sql
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.
在某些情况下,使用In比使用EXISTS更好。通常,如果选择谓词在子查询中,则使用In。如果选择谓词在父查询中,则使用EXISTS。
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403