在SQL中EXISTS和IN之间的区别?

SQL中的EXISTSIN子句有什么区别?

什么时候应该使用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条件语句(如existscount更快,那么这是最有用的。

in有静态列表通过的地方最好使用in

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

当你在一个声明中有一个表时,使用联接更有意义,但大多数情况下应该没有关系。 查询优化器应该返回相同的计划。 在一些实现中(主要是较旧的,如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) 

基于规则优化器

  • 当子查询结果非常大时, EXISTSIN要快得多。
  • 当子查询结果非常小时, INEXISTS更快。

基于成本优化器

  • 没有区别。

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

  1. 当子查询结果非常大时, EXISTSIN快得多。
    当子查询结果非常小时, INEXISTS更快。

     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' 
  2. 查询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将find它们,但查询2不能find空参数。

    我的意思是IN不能和null比较任何东西,所以它没有null的结果,但是EXISTS可以把所有的东西都和null比较。

如果使用IN运算符,则SQL引擎将扫描从内部查询中提取的所有logging。 另一方面,如果我们使用EXISTS ,那么SQL引擎一旦发现匹配就会停止扫描过程。

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

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

IN效率较低,因此Exists速度更快。

我认为,

  • EXISTS是当你需要匹配查询的结果与另一个子查询。 在子查询结果匹配的位置需要检索查询#1的结果。 一种join..例如select客户表#1谁也下了订单表#2

  • IN是检索特定列的值是否位于列表中(1,2,3,4,5)例如,select位于以下邮编中的客户,即zip_code值位于(….)列表中。

什么时候用另一个…当你觉得它适当地阅读(更好地沟通意图)。

区别在于:

 select * from abcTable where exists (select null) 

上面的查询将返回所有logging,而下面的logging将返回空。

 select * from abcTable where abcTable_ID in (select null) 

试一试,观察输出。

IN只支持平等关系(或者在NOT之前有不平等)。
它是= any / = some的一个同义词,例如

 select * from t1 where x in (select x from t2) ; 

EXISTS支持不同types的关系,不能用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 || '℅' ) ; 

而在另一个笔记 –

据称, EXISTSIN之间的性能和技术差异可能是由于特定供应商的实施/限制/错误造成的,但是由于对数据库内部的理解不够,许多时候它们只不过是一个神话而已。

表的定义,统计的准确性,数据库configuration和优化器的版本都影响执行计划,因此影响性能指标。

据我所知,当一个子查询返回一个NULL值,那么整个语句变成NULL 。 在这种情况下,我们使用EXITS关键字。 如果我们想在子查询中比较特定的值,那么我们使用IN关键字。

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

  • 当您的内部查询获取数千行然后EXIST将是更好的select
  • 当你的内部查询获取几行时,那么IN会更快

EXIST评估真或假,但IN比较多个值。 当你不知道logging是否存在时,你应该selectEXIST

原因是EXISTS运营商是基于“至lessfind”原则工作的。 它返回true,并停止扫描表一旦find至less一个匹配的行。

另一方面,当IN操作符与子查询结合使用时,MySQL必须首先处理子查询,然后使用子查询的结果来处理整个查询。

一般的经验法则是,如果子查询包含大量的数据,则EXISTS运算符提供更好的性能。

但是,如果从子查询返回的结果集非常小,则使用IN运算符的查询将执行得更快。

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

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

至于布尔VS比较参数去,要生成一个布尔值两个值需要比较,这是如何条件如何工作。所以我不明白IN和EXISTS如何行为不同。

如果子查询返回多个值,则可能需要执行外部查询 – 如果条件中指定的列内的值与子查询的结果集中的任何值相匹配。 要执行此任务,您需要使用in关键字。

您可以使用子查询来检查是否存在一组logging。 为此,您需要在子查询中使用exists子句。 exists关键字始终返回true或false值。

性能比IN更快。 如果大多数筛选条件在子查询中,那么最好使用IN和如果大多数筛选条件在主查询中,那么最好使用EXISTS。

我相信这有一个直截了当的答案。 你为什么不从在系统中开发这个function的人那里检查呢?

如果您是MS SQL开发人员,则直接从Microsoft获得答案。

IN

确定指定的值是否与子查询或列表中的任何值相匹配。

EXISTS

指定一个子查询来testing行的存在。

我发现使用EXISTS关键字通常非常慢(在Microsoft Access中这是非常正确的)。 我用这种方式来使用连接操作符: 应该使用关键字存在于SQL中

In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.

https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403

如果使用IN运算符,则SQL引擎将扫描从内部查询中提取的所有logging。 另一方面,如果我们使用EXISTS,那么SQL引擎一旦发现匹配就会停止扫描过程。