나는 보통 SQL에서 서브쿼리를 작성할 때
IN과 EXISTS중에 EXISTS가 속도가 더 잘나와서 가능하면 EXISTS를 쓰려고 하는 편이다.
보통 실행계획을 비교하면 더 빠르게 나온다. 그런데 왜 더 빠르지? 그래서 이 주제를 가져와봤다.
실제로 둘은 밀접하거나 비슷한 용도로 많이 쓰이곤 한다.
그냥 떠오르는 예시 od_master라는 주문테이블과 주문상품정보테이블 od_goods 가 있을때 상품명이 '코코냠냠 파우더'인 결제 정보를 가져오는 쿼리를 짜면 다음과 같이 쓸 수 있을 것 같다.
SELECT *
FROM od_master
WHERE odnum IN (SELECT odnum FROM od_goods WHERE gdname = '코코냠냠 파우더')
SELECT *
FROM od_master o
WHERE EXISTS IN (SELECT 1 FROM od_goods g WHERE gdname = '코코냠냠 파우더' AND o.odnum = g.odnum)
| 방식 | 성능 | NULL처리 | |
|---|---|---|---|
| IN | 해당하는 필드가 서브쿼리의 value와 동일한지 비교 | 서브쿼리가 한번 수행 시 메모리에 쌓임. 결과가 많다면 느려질 수 있다! 모든 IN절의 값들과 비교한다. | NULL 비교 이슈가 존재함. |
| EXISTS | 서브쿼리가 반환하는 row가 존재하는 지를 체크 | EXISTS 절 안의 서브쿼리는 외부 쿼리의 각 행에 대해 반복 실행 함. 일치하는 행을 찾다가 확인되면 조건이 True가 되면서 매칭을 멈춤. | 이슈가 없음. (value와 상관없이 row의 존재여부만 확인하기때문.) |
IN이 직관적으로 사람이 읽고 의도를 캐치하기는 더 쉬운 것 같다. 단순하게 IN ('11', '12', '13') 와 같이 value로 직접 비교하는 경우에 IN을 쓰는게 적합하고! 서브쿼리를 쓰는 케이스라면 결과가 아주 작거나 고정적인 경우에 쓰는게 맞을 것 같다.
위에서 설명한 쿼리 예시 케이스에는 EXISTS를 쓰는게 좋다.
즉 EXISTS를 쓰는 케이스는 다른 테이블에 해당하는 row가 존재하는 지 체크하고 싶은 경우다.
실제로 두개의 절(?) 문(?)은 데이터를 필터링하면서 정말 많이 사용한다.
혼용해서 쓰는 경우도 아주 많지만. 둘의 차이를 명확하게 알고 적합하게 사용하시면 좋겠다~
오타나 잘못 설명된 부분이나 잘못된 쿼리 등등등이 있다면 댓글 부탁합니당! 🙇♂️