[sql] NOT EXISTS와 NOT IN과 LEFT JOIN의 차이점은 무엇입니까?

NOT EXISTS, NOT IN 또는 LEFT JOIN WHERE가 NULL 인 경우 SQL 쿼리에서 동일한 작업을 수행 할 수 있습니다. 예를 들면 다음과 같습니다.

SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)

SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)

SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL

모든 구문이 올바른지 확실하지 않지만 이것이 내가 본 일반적인 기술입니다. 왜 다른 것을 사용하기로합니까? 성능이 다른가요? 이 중 가장 빠르거나 가장 효율적인 것은 무엇입니까? (구현에 따라 달라지면 언제 사용합니까?)



답변

간단히 말해서 :

NOT IN조금 다릅니다 : NULL목록에 하나만 있는 경우 절대 일치하지 않습니다 .

  • 에서 MySQL, NOT EXISTS조금 덜 효율적이다

  • 에서가 SQL Server, LEFT JOIN / IS NULL덜 효율적이다

  • 에서가 PostgreSQL, NOT IN덜 효율적이다

  • 에서 Oracle세 가지 방법은 모두 동일합니다.


답변

데이터베이스가 쿼리를 최적화하는 데 능숙하면 두 번째는 세 번째에 가까운 것으로 변환됩니다.

질문에있는 것과 같은 간단한 상황의 경우 모두 조인으로 실행되므로 차이가 거의 없거나 전혀 없어야합니다. 보다 복잡한 쿼리에서는 데이터베이스가 not innot exists쿼리를 조인하지 못할 수 있습니다 . 이 경우 쿼리 속도가 훨씬 느려집니다. 반면, 사용할 수있는 인덱스가없는 경우에도 조인이 제대로 수행되지 않을 수 있으므로 조인을 사용한다고해서 안전하다는 의미는 아닙니다. 성능 문제가 있는지 확인하려면 쿼리의 실행 계획을 조사해야합니다.


답변

널을 피한다고 가정하면 표준 SQL을 사용하여 결합 방지 를 작성하는 모든 방법입니다 .

명백한 생략은 다음을 사용하는 것과 같습니다 EXCEPT.

SELECT a FROM table1
EXCEPT
SELECT a FROM table2

Oracle에서는 MINUS연산자 를 사용해야합니다 (아마도 더 나은 이름).

SELECT a FROM table1
MINUS
SELECT a FROM table2

독점적 인 구문에 관해서는 OUTER APPLYSQL Server에서 사용하는 제품에 따라 조사 할 가치가있는 비표준 등가물이있을 수도 있습니다 ( 예 :

SELECT t1.a
  FROM table1 t1
       OUTER APPLY
       (
        SELECT t2.a
          FROM table2 t2
         WHERE t2.a = t1.a
       ) AS dt1
 WHERE dt1.a IS NULL;


답변

다중 필드 기본 키를 사용하여 테이블에 데이터를 삽입해야하는 경우 Access에서 시도했지만 모든 데이터베이스에서는 “테이블에 ‘이러한’값이있는 레코드가 없는지”확인하지 않는 것이 훨씬 빠릅니다. -오히려 테이블에 삽입하면 초과 키 (키로)가 두 번 삽입되지 않습니다.


답변

NOT IN, NOT EXISTS 등과 같은 역 키워드는 항상 성능 관점에서 사용하지 마십시오. 역 항목을 확인하려면 DBMS가 사용 가능한 모든 항목을 통해 실행하고 역 선택을 삭제해야합니다.


답변