생계/튜닝2019. 11. 1. 15:03
반응형

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
Posted by 돌고래트레이너