Programing

SQL에서 EXISTS와 IN의 차이점은 무엇입니까?

lottogame 2020. 2. 19. 21:19
반응형

SQL에서 EXISTS와 IN의 차이점은 무엇입니까?


SQL 에서 EXISTSand 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조건문 이있는 경우 가장 유용합니다 .existscount

in당신이 전달하는 정적 목록이 어디에 가장 사용된다 :

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

in명령문에 테이블이 있으면를 사용하는 것이 더 합리적 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)

규칙 최적화 프로그램을 기반으로 :

  • EXISTSIN하위 쿼리 결과가 매우 큰 경우 보다 훨씬 빠릅니다 .
  • INEXISTS하위 쿼리 결과가 매우 작을 때보 다 빠릅니다 .

비용 최적화 도구를 기반으로 :

  • 다른 점이 없다.

나는 그들이 당신이하는 일을 알고 따라서 다르게 사용된다고 가정하므로, 나는 당신의 질문을 다음과 같이 이해할 것입니다 : 언제 EXISTS 대신 IN을 사용하도록 SQL을 다시 작성하는 것이 좋을까요, 그 반대도 마찬가지입니다.

이것이 공정한 가정입니까?


편집 : 내가 묻는 이유는 많은 경우 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 가하는 일에 대해 궁금해하고 그것을 사용하는 방법을 알고 있습니까? 아니면 EXISTS를 대신하여 IN을 사용하여 SQL을 다시 작성하거나 그 반대로 사용하는 것이 좋은 생각입니까?


  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 )
    

    t1id에 null 값이 있으면 Query 1이 값을 찾지 만 Query 2는 null 매개 변수를 찾을 수 없습니다.

    내 말 IN은 아무것도 null과 비교할 수 없으므로 null에 대한 결과는 없지만 EXISTS모든 것을 null과 비교할 수 있다는 의미 입니다.


IN연산자를 사용하는 경우 SQL 엔진은 내부 쿼리에서 가져온 모든 레코드를 스캔합니다. 반면에을 사용하는 경우 EXISTSSQL 엔진은 일치하는 것을 발견하자마자 스캔 프로세스를 중지합니다.


Exists키워드는 참 또는 거짓으로 평가하지만, IN해당 서브 쿼리 열의 모든 값을 비교하는 키워드. 다른 하나 Select 1Exists명령 과 함께 사용할 수 있습니다 . 예:

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)
;

EXISTSIN을 사용하여 표현할 수없는 다양한 유형의 관계를 지원합니다 . 예 :-

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의 성능 및 기술적 차이는 특정 공급 업체의 구현 / 제한 / 버그로 인해 발생할 수 있지만 데이터베이스 내부에 대한 이해 부족으로 인해 신화에 지나지 않습니다.

테이블 정의, 통계 정확도, 데이터베이스 구성 및 옵티 마이저 버전은 모두 실행 계획 및 성능 메트릭에 영향을 미칩니다.


내 생각 엔

  • EXISTS쿼리 결과를 다른 하위 쿼리와 일치시켜야 할 때입니다. SubQuery 결과가 일치하는 위치에서 Query # 1 결과를 검색해야합니다. Join of Kind .. 예를 들어 주문 테이블 # 2도 배치 한 고객 테이블 # 1을 선택하십시오.

  • IN은 특정 열의 값이 IN목록 (1,2,3,4,5)에 있는지 검색하는 것입니다. 예를 들어 다음 우편 번호에있는 고객을 선택하십시오. 즉 zip_code 값은 (....) 목록에 있습니다.

적절하게 읽는다고 생각 될 때 (의사 소통이 더 나을 때).


차이점은 다음과 같습니다.

select * 
from abcTable
where exists (select null)

위의 쿼리는 모든 레코드를 반환하지만 아래의 쿼리는 빈 레코드를 반환합니다.

select *
from abcTable
where abcTable_ID in (select null)

시도하고 출력을 관찰하십시오.


내 지식에 따라 하위 쿼리가 NULL값을 반환 하면 전체 문이됩니다 NULL. 이 경우 EXITS키워드를 사용하고 있습니다. 하위 쿼리에서 특정 값을 비교하려면 IN키워드를 사용합니다 .


내부 쿼리에서 가져온 쿼리 수에 따라 속도가 더 빠릅니다.

  • 내부 쿼리가 수천 개의 행을 가져 오는 경우 EXIST가 더 좋습니다.
  • 내부 쿼리에서 몇 개의 행을 가져 오면 IN이 더 빠릅니다.

EXIST는 true 또는 false로 평가되지만 IN은 여러 값을 비교합니다. 기록이 존재하는지 모르는 경우 EXIST를 선택해야합니다.


그 이유는 EXISTS 연산자가 "적어도 발견 된"원칙에 따라 작동하기 때문입니다. 일치하는 행이 하나 이상 발견되면 true를 리턴하고 테이블 스캔을 중지합니다.

반면에 IN 연산자가 하위 쿼리와 결합되면 MySQL은 먼저 하위 쿼리를 처리 한 다음 하위 쿼리 결과를 사용하여 전체 쿼리를 처리해야합니다.

일반적으로 하위 쿼리에 많은 양의 데이터가 포함 된 경우 EXISTS 연산자는 더 나은 성능을 제공합니다.

그러나 서브 쿼리에서 리턴 된 결과 세트가 매우 작은 경우 IN 연산자를 사용하는 쿼리가 더 빠르게 수행됩니다.


우리가 NULL 값을 다루지 않는 한 둘 다 동일해야한다는 것을 이해합니다.

쿼리가 = NULL 값을 반환하지 않는 것과 같은 이유는 NULL입니다. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

부울 대 비교기 인수에 관해서는 부울을 생성하려면 두 값을 비교해야하며 그것이 if 조건이 작동하는 방식입니다. 따라서 IN과 EXISTS가 어떻게 다르게 동작하는지 이해하지 못합니다.


하위 쿼리가 둘 이상의 값을 반환하면 조건에 지정된 열 내의 값이 하위 쿼리 결과 집합의 값과 일치하는 경우 외부 쿼리를 실행해야 할 수 있습니다. 이 작업을 수행하려면 in키워드 를 사용해야합니다 .

서브 쿼리를 사용하여 레코드 세트가 있는지 확인할 수 있습니다. 이를 위해 exists하위 쿼리와 함께 절 을 사용해야합니다 . exists키워드는 항상 true 또는 false 값을 반환합니다.


나는 이것이 정답이라고 생각합니다. 시스템에서 해당 기능을 개발 한 사람들로부터 왜 확인하지 않습니까?

MS SQL 개발자 인 경우 다음은 Microsoft의 답변입니다.

IN:

지정된 값이 하위 쿼리 또는 목록의 값과 일치하는지 확인합니다.

EXISTS:

행이 있는지 테스트 할 하위 쿼리를 지정합니다.


EXISTS 키워드 사용이 종종 느리다는 것을 알았습니다 (Microsoft Access에서는 매우 그렇습니다). 대신 이런 식으로 조인 연산자를 사용합니다 : should-i-use-the-keyword-exists-in-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보다 빠릅니다. 대부분의 필터 기준이 하위 쿼리에 있으면 IN을 사용하는 것이 좋으며 대부분의 필터 기준이 기본 쿼리에 있으면 EXISTS를 사용하는 것이 좋습니다.


IN 연산자를 사용하는 경우 SQL 엔진은 내부 쿼리에서 가져온 모든 레코드를 스캔합니다. 반면에 EXISTS를 사용하는 경우 SQL 엔진은 일치하는 것을 발견하자마자 스캔 프로세스를 중지합니다.

참고 URL : https://stackoverflow.com/questions/24929/difference-between-exists-and-in-in-sql



반응형