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

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


当前回答

哪个更快取决于内部查询获取的查询数量:

当您的内部查询获取数千行,那么EXIST将是更好的选择 当您的内部查询获取少量行时,那么IN将更快

EXIST对true或false进行评估,但在比较多个值。当你不知道记录是否存在时,你应该选择exist

其他回答

Exists关键字计算true或false,而IN关键字比较相应子查询列中的所有值。 另一个Select 1可与Exists命令一起使用。例子:

SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)

但IN的效率较低,所以存在更快。

exists关键字可以这样使用,但实际上它是为了避免计数:

--this statement needs to check the entire table
select count(*) from [table] where ...

--this statement is true as soon as one match is found
exists ( select * from [table] where ... )

这是最有用的if条件语句,as exists可以比count快得多。

in最好用在你有一个静态列表要传递的地方:

 select * from [table]
 where [field] in (1, 2, 3)

当在in语句中有一个表时,使用连接更有意义,但大多数情况下这并不重要。无论哪种方式,查询优化器都应该返回相同的计划。在一些实现中(大多数是旧的,如Microsoft SQL Server 2000),查询将总是获得嵌套的连接计划,而连接查询将适当地使用嵌套、合并或散列。更现代的实现更智能,甚至可以在使用in时调整计划。

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

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

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

我假设您知道它们的作用,因此使用方式不同,所以我将把您的问题理解为:什么时候重写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,反之亦然,将是一个好主意?

EXISTS将告诉您查询是否返回了任何结果。例如:

SELECT * 
FROM Orders o 
WHERE EXISTS (
    SELECT * 
    FROM Products p 
    WHERE p.ProductNumber = o.ProductNumber)

IN用于将一个值与多个值进行比较,并且可以使用文字值,如下所示:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (1, 10, 100)

你也可以用IN子句来使用查询结果,就像这样:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)