본문 바로가기
프로그래밍

[SQL] (NOT)EXISTS 와 (NOT)IN 비교하기

by choihyuunmin 2023. 4. 17.
728x90

 최근 작업하고 있는 모듈에서 A 테이블과 B 테이블을 비교하여 B 테이블에 없는 값을 A 테이블에서 가져오는 작업을 진행하고 있다. 처음에는 NOT IN 구문을 사용하여 비교하고 가져오고 있었는데, NOT EXISTS 를 사용하면 더 효과적이라는 말을 듣고, 궁금증에 여기저기 검색해보았다. 결론적으로 말하자면 조회 건수가 많지 않은 쿼리에서는 성능이 비슷하지만, 조회 건수가 급격하게 늘어나면 (NOT)EXISTS 구문이 훨씬 효과적이라는 것이다.

초기 데이터

테이블은 rel1 , rel2 테이블을 생성하였다.

rel1
rel2

 

1. (NOT) IN

SELECT * FROM rel1
WHERE number IN (SELECT number FROM rel2);


SELECT * FROM rel1
WHERE number NOT IN (SELECT number FROM rel2);

 

 

IN 구문에서는 가장 먼저 서브쿼리(위에서는 rel2) 를 실행하여 number 요소들을 가져온다.
그 다음에는 메인쿼리의 rel1 에서 row를 하나를 가져오고,
서브쿼리의 row들과 메인쿼리의 row 를 비교하여 같은 것만 반환하게 된다.
위의 과정을 메인쿼리의 row 개수만큼 반복하여 비교한다.

IN 구문은 서브쿼리와 메인쿼리의 값 중 하나라도 일치하면 반환해주지만, NOT IN 쿼리는 모든 요소들과 일치하지 않는 값을 체크하여 반환해주게 된다. 여기서 NULL 값은 DB에서 비교연산을 할 때 항상 UNKNOWN(FALSE) 값을 반환하기 때문에 NULL 이 존재하면 아무 결과도 확인할 수 없다. 원하는 값을 보려면 NULL을 제외하고 조회하면 된다.(WHERE number IS NOT NULL)

 

 

2. (NOT) EXISTS


SELECT * FROM rel1 t1
WHERE EXISTS (SELECT 1 FROM rel2 t2 WHERE t1.number = t2.number);



SELECT * FROM rel1 t1
WHERE NOT EXISTS (SELECT 1 FROM rel2 t2 WHERE t1.number = t2.number);

 

 

EXISTS 구문에서는 IN 구문과 달리 메인쿼리에 먼저 접근하여 row 를 하나 가져오고 EXISTS 의 서브쿼리를 실행시켜
결과가 존재하는지를 판단한다. 서브쿼리의 결과가 TRUE 인지 FALSE 인지 체크하기 떄문에 EXISTS 에서는 TRUE 면
메인쿼리의 결과를 출력하고, NOT EXISTS 에서는 서브쿼리 내 결과가 FALSE 면 메인쿼리의 결과를 출력한다.
여기서 주의할 부분은, 서브쿼리에서 TRUE만 되면 레코드가 출력되기 때문에 두 테이블에서 같은 값을 가져오려면
WHERE 절로 조건을 주어야한다.

NOT EXISTS 에서는 서브쿼리의 결과가 FALSE 면 반환되게 된다. 서브쿼리에서 rel1 과 rel2 의 조인 시 NULL은 위에 IN 에서 설명한 것처럼 비교연산에서 빠지게 되며, 이는 서브쿼리를 FALSE 로 만들고, TRUE가 되어서 NULL 값이 같이 빠져나오게 된다. 그러므로 IN 에서는 나오지 않은 NULL 값이 NOT EXISTS 에서는 나오는 것을 확인할 수 있다.

 

3. 정리

  • (NOT) IN : 실제 데이터들의 값을 비교하여 일치하는지 확인한다. 특정 값 목록을 기반으로 필터링한다.
  • (NOT) EXISTS : 해당 ROW 가 존재하는지만 확인하여, TRUE 혹은 FALSE 를 반환한다. 서브쿼리에서 행의 부재를 기반으로 필터링한다.
  • NULL 과의 비교는 항상 UNKNOWN(FALSE) 값을 반환한다.

참조

https://kimeunyeol.tistory.com/m/30

 

SQL - [NOT] IN과 [NOT] EXISTS의 차이

1. EXISTS : 단순히 EXISTS 절의 결과 존재 유무만으로 T/F 반환 메인 쿼리 EXISTS(서브 쿼리) :  서브 쿼리의 결과가 " 한 건이라도 존재하면" TRUE 없으면 FALSE를 리턴한다. 먼저 메인쿼리에 접근하여

kimeunyeol.tistory.com

https://hoon93.tistory.com/31

 

[Oracle] IN, EXISTS, NOT IN, NOT EXISTS 특징 및 비교

다중 행(Multi Row) 서브쿼리 IN과 EXISTS 실행 순서 및 특징 1) IN : 실제 존재(일치)하는 데이터들의 모든 값까지 확인. ① SubQuery를 먼저 실행하여 출력되는 그에 대한 모든 row가져옴(따라서 사실 IN뒤

hoon93.tistory.com

https://blog.naver.com/PostView.nhn?blogId=wesable&logNo=9644957&parentCategoryNo=&categoryNo=35&viewDate=&isShowPopularPosts=true&from=search 

 

NOT IN과 NOT EXISTS의 차이점

이번달 퀴즈는 두가지 부정형 조인 NOT IN, NOT EXISTS 의 차이점을 설명하는것입니다. 문제...

blog.naver.com

https://doorbw.tistory.com/222

 

[MS SQL Server] #11_ IN / EXISTS / NOT IN / NOT EXISTS 비교

안녕하세요 문범우입니다. 이번 포스팅에서는 IN, EXISTS, NOT IN, NOT EXISTS 에 대해서 보다 상세하게 알아보려고 합니다. 해당 내용은 꼭 SQL Server 뿐만 아니라 MySQL 등에서도 포괄적으로 적용되는 내

doorbw.tistory.com