EXISTS
和IN
在SQL中有何区别?
何时应使用EXISTS
,何时应使用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
的时候非常有用,因为 exists
比 count
更快。
in
最好用于你要传递静态列表的情况: select * from [table]
where [field] in (1, 2, 3)
in
语句中有一个表时,使用join
更有意义,但大多数情况下并不重要。查询优化器应该以相同的方式返回相同的计划。在一些实现中(主要是旧版本,如Microsoft SQL Server 2000),in
查询将始终获得nested join计划,而join
查询将适当地使用嵌套、merge或hash。更现代的实现更加智能,即使使用in
也可以调整计划。EXISTS
可以告诉你一个查询是否返回任何结果。例如:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN
用于将一个值与多个值进行比较,可以使用文字值,例如:
IN
是一种在SQL中使用的运算符,用于指定要匹配的多个值。它可以与列名或常量值一起使用,以检索满足条件的行。
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
您也可以使用查询结果与 IN
子句一起使用,就像这样:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
基于规则优化器:
EXISTS
在子查询结果非常大的情况下比IN
更快。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的作用及如何使用,还是询问是否将使用IN的SQL重写为使用EXISTS,或者反过来,是否是个好主意?JOIN
中,你需要使用DISTINCT
。 - JaiderEXISTS
在子查询结果非常大时比IN
要快。IN
在子查询结果非常小时比EXISTS
要快。
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'
查询1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
查询 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
如果在t1
中你的id为空值,则查询1可以找到它们,但查询2无法找到空参数。
我的意思是IN
不能将任何内容与null进行比较,因此对于null没有结果,但EXISTS
可以将任何内容与null进行比较。
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 || '℅'
)
;
EXISTS 和 IN 之间据称的性能和技术差异可能是由于特定供应商的实现/限制/错误,但很多情况下它们只是由于对数据库内部机制缺乏理解而产生的谬论。
表定义、统计数据准确性、数据库配置和优化器版本都会影响执行计划,从而影响性能指标。
如果您正在使用IN
运算符,SQL引擎将扫描从内部查询获取的所有记录。另一方面,如果我们使用EXISTS
,SQL引擎将在找到匹配项后停止扫描过程。
Exists
关键字的作用是判断是否存在符合条件的行,返回true或false。而IN
关键字将对应子查询列中的所有值进行比较。
另外,Select 1
可与Exists
命令一起使用。例如:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
但是IN
的效率较低,因此Exists
更快。
EXISTS
是当你需要将查询结果与另一个子查询进行匹配时使用的。
需要检索出 SubQuery 结果与之匹配的 Query#1 结果。类似于 Join..
例如:选择那些在 table#2 中也下单过的 customers table#1。
IN 是用来检索特定列的值是否位于列表中(1、2、3、4、5)IN
。
例如:选择那些邮编在(...)列表中的客户,即 zip_code 值位于(...)列表中。
select *
from abcTable
where exists (select null)
select *
from abcTable
where abcTable_ID in (select null)
table
中的所有列,而第二个查询返回table
和table2
中的所有内容。在一些(主要是旧的)SQL数据库中,in
查询将被实现为嵌套连接,而join
查询可以被嵌套、合并、哈希等等 - 以最快的方式实现。 - Keithexists
can be used within a case statement, so they can be handy that way also i.e.select case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
- smooth_smoothie