SQL中的EXISTS子句和IN子句有什么区别?
什么时候应该使用EXISTS,什么时候应该使用IN?
SQL中的EXISTS子句和IN子句有什么区别?
什么时候应该使用EXISTS,什么时候应该使用IN?
当前回答
如果子查询返回多个值,则可能需要执行外层查询—如果条件中指定的列中的值与子查询结果集中的任何值匹配。要执行此任务,需要使用in关键字。
您可以使用子查询来检查一组记录是否存在。为此,您需要使用exists子查询子句。exists关键字总是返回true或false值。
其他回答
如果使用IN操作符,SQL引擎将扫描从内部查询中获取的所有记录。另一方面,如果我们使用EXISTS, SQL引擎将在找到匹配项后立即停止扫描过程。
不同之处在于:
select *
from abcTable
where exists (select null)
上面的查询将返回所有记录,而下面的查询将返回空。
select *
from abcTable
where abcTable_ID in (select null)
尝试一下并观察输出。
在某些情况下,使用In比使用EXISTS更好。通常,如果选择谓词在子查询中,则使用In。如果选择谓词在父查询中,则使用EXISTS。
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
我假设您知道它们的作用,因此使用方式不同,所以我将把您的问题理解为:什么时候重写SQL以使用IN而不是EXISTS是一个好主意,或者反之亦然。
这个假设合理吗?
编辑:我问的原因是,在许多情况下,您可以重写基于in的SQL来使用EXISTS,反之亦然,对于某些数据库引擎,查询优化器将区别对待这两者。
例如:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
可以改写为:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
或者用join:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
所以我的问题仍然存在,原来的海报想知道什么是IN和EXISTS,因此如何使用它,或者他问是否重写SQL使用IN使用EXISTS,反之亦然,将是一个好主意?
如果你可以用where in代替where exists,那么where in可能更快。
使用where in或where exists 将遍历父结果的所有结果。不同之处在于where exists将导致大量依赖子查询。如果你可以防止依赖子查询,那么where in将是更好的选择。
例子
假设我们有10,000家公司,每家公司有10个用户(因此我们的用户表有100,000个条目)。现在假设您希望通过用户名或公司名查找用户。
下面使用were exists查询的执行时间为141ms:
select * from `users`
where `first_name` ='gates'
or exists
(
select * from `companies`
where `users`.`company_id` = `companies`.`id`
and `name` = 'gates'
)
这是因为对每个用户执行一个依赖子查询:
然而,如果我们避免exists查询并使用:
select * from `users`
where `first_name` ='gates'
or users.company_id in
(
select id from `companies`
where `name` = 'gates'
)
然后避免依赖子查询,查询将在0,012毫秒内运行