SQL中的EXISTS
和IN
子句有什么区别?
我们应该何时使用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
声明中有一个表时,使用a更有意义join
,但大多数情况下它并不重要.查询优化器应该以任一方式返回相同的计划.在某些实现中(大多数较旧,如Microsoft SQL Server 2000),in
查询将始终获得嵌套连接计划,而join
查询将根据需要使用嵌套,合并或散列.更现代的实现更加智能,即使在in
使用时也可以调整计划.
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)
根据规则优化:
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 )
或者加入:
SELECT Customers.* FROM Customers INNER JOIN Orders ON Customers.ID = Orders.CustomerID
所以我的问题仍然存在,是原始海报想知道IN和EXISTS做了什么,以及如何使用它,或者他是否要求使用IN来重写SQL而不是使用EXISTS,反之亦然?
EXISTS
比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中有null值,那么Query 1会找到它们,但是查询2无法找到null参数.
我的意思是IN
无法与null进行比较,因此它没有null的结果,但EXISTS
可以将所有内容与null进行比较.
如果您使用的是IN
运算符,则SQL引擎将扫描从内部查询中提取的所有记录.另一方面,如果我们使用EXISTS
,SQL引擎会在找到匹配后立即停止扫描过程.
该Exists
关键字计算真或假,但IN
关键字比较在相应的子查询列的所有值.另一个Select 1
可以与Exists
命令一起使用.例:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
但IN
效率低下这么Exists
快.
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之间的性能和技术差异可能来自特定供应商的实施/限制/错误,但很多时候它们只不过是因为对数据库内部缺乏了解而产生的神话.
表的定义,统计信息的准确性,数据库配置和优化程序的版本都会对执行计划产生影响,从而影响性能指标.
我认为,
EXISTS
是什么时候需要将查询结果与另一个子查询匹配.在SubQuery结果匹配的情况下,需要检索查询#1结果.加入的种类..例如,选择已下订单#2的客户表#1
IN是检索特定列的值是否位于IN
列表中(1,2,3,4,5)例如,选择位于以下zipcodes中的客户,即zip_code值位于(....)列表中.
什么时候使用一个...当你觉得它读得合适时(更好地传达意图).