not in 서브쿼리를 사용해서 결과 rows 를 필터하고 싶은 경우가 있다.
그때 제외하고 싶은 조건이 추가 되거나 할때 단순하게 아래와 같이 쓰는 경우가 있다.
SELECT *
FROM A
WHERE ...
AND NOT ( (A.COL1, A.COL2) IN ( SELECT
FROM B
WHERE ... )
OR (A.COL1, A.COL3) IN ( SELECT
FROM B
WHERE ... )
)
컬럼의 갯수는 동일하지만 대상 컬럼은 바뀌었다.
위 쿼리는 업무를 그대로 풀어서 가독성은 있지만 성능상의 불리함이 있다.
NOT IN 절을 바꿔보자
AND NOT ((A.COL1, A.COL2, A.COL3) IN ( SELECT B.COL1
,DECODE(RN,1,B.COL2, A.COL2)
,DECODE(RN,1,A.COL3, B.COL3)
FROM B,
( SELECT ROWNUM RN
FROM ALL_OBJECTS
WHERE ROWNUM <=2
)BB
WHERE ...
)
)
조건에 따라서 COL1, COL2 또는 COL1,COL3 와 가공의 컬럼 RN 을 만들고 카티션 조인을 한다.
RN=1 인 경우 원본의 첫번째 NOT IN 이 되고
RN=2 인 경우 원본의 두번째 NOT IN 이 된다.
EX) RN=1 AND NOT ((A.COL1, A.COL2, A.COL3) IN ( B.COL1, B.COL2, A.COL3 )
RN=2 AND NOT ((A.COL1, A.COL2, A.COL3) IN ( B.COL1, A.COL2, B.COL3 )
동일 컬럼의 비교는 항상 참이 되어 결국 결과는 아래와 같다.
RN=1 AND NOT ((A.COL1, A.COL2) IN ( B.COL1, B.COL2 )
RN=2 AND NOT ((A.COL1, A.COL3) IN ( B.COL1, B.COL3 )
'생계 > 튜닝' 카테고리의 다른 글
mysql 실행계획 확인하기 (0) | 2024.11.25 |
---|---|
rac 환경 통계수집 후 no_invalidate (0) | 2023.06.10 |
오라클 AWR 사용하기 (0) | 2023.05.13 |
[SQL]열거된 OR 제거하기. IN 사용 (0) | 2020.11.13 |
[SQL] 전월 증감 리포트 (0) | 2019.11.01 |