JaeWon's Devlog
article thumbnail
반응형

1. EXISTS 절

- 결과로 TRUE, FALSE 를 반환하는 연산자.

- 한 테이블이 다른 테이블과 외래키(FK)와 같은 관계인 경우 유용합니다.

- 조건에 해당하는 ROW의 존재 유무 이후 더 수행하지 않는다.

- 즉, 테이블 간의 결과를 어떤 값이 존재하는 지만 조회 할때 사용합니다.

- 쿼리의 의도롤 고려했을 대 EXISTS 가 IN 에 비해 성능이 좋습니다.(그렇지 않을 경우, JOIN 활용)

EXIST
- 메인 쿼리 -> EXISTS 쿼리 순서로 진행
-- 기본 구문
SELECT 
    *
FROM
    table
WHERE
    [NOT] EXISTS(subquery);

1-1. 예제

- 아래와 같이 간단하게 데이터를 만들고 확인해보겠습니다.

SELECT * FROM STUDENT_TABLE;

SELECT * FROM DEPARTMENT_TABLE;

- EXISTS 절을 사용하여 두 개의 테이블 중 조건에 맞는 ROW 들만 추출합니다.

SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    EXISTS (SELECT 1
    	    FROM DEPARTMENT_TABLE B
            WHERE A.department_id = B.department_id)
;

 

- 반대로 조건에 맞지 않는 ROW 들만 추출하고자 한다면 앞에 NOT EXISTS 절을 사용합니다.

SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    NOT EXISTS (SELECT 1
    	    FROM DEPARTMENT_TABLE B
            WHERE A.department_id = B.department_id)
;

2. IN 절

- 집합 내부에 값이 존재하는지 여부를 확인합니다.

- 존재하는 데이터의 값을 비교하기 때문에 EXISTS 절보다 속도가 느린 경우가 존재합니다.

- 조건의 범위를 지정하는데 사용합니다.

IN
- IN 쿼리 -> 메인 쿼리 순서로 진행
-- 기본 구문
SELECT 
    *
FROM
    table
WHERE
    something [NOT] IN ("", "", "" ...);
    
-- 서브 쿼리
SELECT 
    *
FROM
    table
WHERE
    something [NOT] IN (select something from table2);
참고!!!
NOT IN에 경우에 조건에 맞는 데이터가 있어도 중간에 NULL이 존재하게되면 no rows selected가 나오게 되니 NVL 처리로 NULL 처리를 해야합니다.

2-1. 예제

- 아래와 같이 간단하게 데이터를 만들고 확인해보겠습니다.

SELECT * FROM STUDENT_TABLE;

SELECT * FROM DEPARTMENT_TABLE;

- IN 절을 사용하여 테이블 중 조건에 맞는 데이터 들만 추출합니다.

SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    department_id IN ('1001', '2002', '3002')
;

결과 사진

- NOT IN 절 사용 시 STUDENT_TABLE 에 NULL 값이 포함되어 있기 때문에 검색시 no rows selected 가 발생합니다.

SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    department_id NOT IN (SELECT department_id FROM DEPARTMENT_TABLE)
;

결과 사진

- NVL 처리하여 정상적으로 조회되도록 수정합니다.

SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    department_id NOT IN (SELECT NVL(department_id, '0000') FROM DEPARTMENT_TABLE)
;

결과사진

3. 비교

- 보통 연산자를 사용하는 쿼리에서는 IN 절보다 EXISTS 절을 사용하는 쿼리가 성능이 좋습니다.

- EXISTS 절은 "at least found(최소 발견???)" 원칙에 따라 작동함에 따라, 일치하는 행이 발견되면 테이블 스캔을 중지합니다.

- 반면에, IN 절은 하위 쿼리와 결합하게 되면 MySQL은 서브 쿼리를 먼저 처리한 다음 서브 쿼리의 결과를 가지고 다시 메인 쿼리를 처리합니다.

- 그렇기 때문에, 일반적으로 서브 쿼리에 데이터가 많이 포함되어 있으면 EXISTS 절이 더 좋은 성능을 제공하고, 데이터가 적거나, 작은 연산자를 사용하는 쿼리에 대해서는 IN 절이 더 좋은 성능을 제공하게 됩니다.


참고

- https://www.mysqltutorial.org/mysql-exists/

- https://wedul.site/450

반응형
profile

JaeWon's Devlog

@Wonol

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!