SQL中EXISTS和IN的区别?

时间:2008-08-24 08:42:24

标签: sql

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

我们应该何时使用EXISTS,何时应该使用IN

20 个答案:

答案 0 :(得分:214)

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或{{ 3}}酌情。更现代的实现更智能,即使使用in也可以调整计划。

答案 1 :(得分:117)

EXISTS会告诉您查询是否返回任何结果。 e.g:

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)

答案 2 :(得分:81)

基于规则优化器

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

基于费用优化工具

  • 没有区别。

答案 3 :(得分:40)

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

答案 4 :(得分:28)

    当子查询结果非常大时,
  1. EXISTSIN快得多。
    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'
    
  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将找到它们,但查询2无法找到空参数。

    我的意思是IN无法将任何内容与null进行比较,因此它没有null的结果,但EXISTS可以将所有内容与null进行比较。

答案 5 :(得分:16)

如果您使用IN运算符,SQL引擎将扫描从内部查询中提取的所有记录。另一方面,如果我们使用EXISTS,SQL引擎会在找到匹配后立即停止扫描过程。

答案 6 :(得分:10)

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 之间的性能和技术差异可能来自特定供应商的实施/限制/错误,但很多时候它们只不过是神话由于缺乏对数据库内部的理解而创建。

表格'定义,统计'准确性,数据库配置和优化程序的版本都会对执行计划产生影响,从而对性能指标产生影响。

答案 7 :(得分:9)

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

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

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

答案 8 :(得分:5)

我想,

  • EXISTS是您需要将查询结果与其他子查询匹配的时间。 在SubQuery结果匹配的情况下,需要检索查询#1结果。加入的种类.. 例如。选择已下订单表#2的客户表#1

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

什么时候使用一个...当你觉得它读得合适时(更好地传达意图)。

答案 9 :(得分:4)

差异在于:

select * 
from abcTable
where exists (select null)

上面的查询将返回所有记录,而下面的一个记录将返回空。

select *
from abcTable
where abcTable_ID in (select null)

试一试并观察输出。

答案 10 :(得分:3)

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

答案 11 :(得分:3)

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

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

EXIST评估true或false,但IN比较多个值。如果您不知道记录是否存在,则应选择EXIST

答案 12 :(得分:1)

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

查询未返回= NULL vs的值的原因与NULL相同。 {{3}}

至于boolean vs comparator参数,要生成布尔值,需要比较两个值,这就是任何if条件的工作原理。所以我无法理解IN和EXISTS的行为方式如何 。

答案 13 :(得分:0)

IN:

  • 处理列表结果集
  • 无法处理导致多表虚拟表的子查询
  • 比较结果列表中的每个值
  • 对于较大的子查询结果集,性能相对较慢

存在:

  • 在虚拟表上工作
  • 与关联查询一起使用
  • 找到匹配项后退出比较
  • 对于较大的子查询结果集,性能相对较快

答案 14 :(得分:0)

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

答案 15 :(得分:0)

我发现使用EXISTS关键字通常很慢(在Microsoft Access中非常正确)。 我改为以这种方式使用join运算符: should-i-use-the-keyword-exists-in-sql

答案 16 :(得分:0)

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

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

IN

  

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

EXISTS

  

指定要测试行是否存在的子查询。

答案 17 :(得分:0)

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

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

答案 18 :(得分:-1)

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

答案 19 :(得分:-2)

如果使用IN运算符,SQL引擎将扫描从内部查询中提取的所有记录。另一方面,如果我们使用EXISTS,SQL引擎会在找到匹配后立即停止扫描过程。