Web Programming/DB
[ORACLE/오라클] EXISTS, NOT EXISTS, 조건절 서브쿼리 성능(속도) 개선
jaey0ng
2023. 6. 14. 10:25
개선 전: 4n초
개선 후: 1.n초
로 약 40초가량 성능이 개선된 경험을 토대로 글을 작성합니다.
EXISTS 개선
개선 전 코드입니다
AND EXISTS (SELECT 1
FROM TBL1 A
WHERE 1=1
AND A.COL = (SELECT MIN(B.COL B)
FROM TBL2 B
WHERE 1=1
AND #{ROW} IS NOT NULL AND B.ROW = #{ROW}
)
AND ~~
AND ~~
)
위 코드 중
AND A.COL = (SELECT MIN(B.COL B)
FROM TBL2 B
WHERE 1=1
AND #{ROW} IS NOT NULL AND B.ROW = #{ROW}
)
가 원인이 되었습니다.
서브쿼리에 조건을 걸어둬서 빠를 것이라고 예상했지만
처리순서가 후순위 처리가 되어 절차가 늘어나면서 느려진 것으로 예상됩니다…
개선 후 코드입니다
AND EXISTS (SELECT 1
FROM TBL1 A
, (SELECT MIN(B.COL) AS COL
, B.ROW
FROM TBL2 B
WHERE 1=1
AND #{ROW} IS NOT NULL AND B.ROW = #{ROW}
GROUP BY COL
, B.ROW
) B
WHERE 1=1
AND A.COL = B.COL
AND ~~
AND ~~
)
조건절 서브쿼리에서
조인문으로 바꾸면서 개선된 케이스입니다.
NOT EXISTS 개선
개선 전 코드입니다
AND NOT EXISTS (SELECT 1
FROM TBL1 A
WHERE 1=1
AND A.COL = (SELECT MIN(B.COL B)
FROM TBL2 B
WHERE 1=1
AND #{ROW} IS NOT NULL AND B.ROW = #{ROW}
)
AND ~~
AND ~~
)
원인은 EXISTS와 동일합니다.
개선 후 코드입니다
AND NOT EXISTS (SELECT 1
FROM TBL1 A
, (SELECT MIN(B.COL) AS COL
, B.ROW
FROM TBL2 B
WHERE 1=1
AND #{ROW} IS NOT NULL AND B.ROW = #{ROW}
GROUP BY COL
, B.ROW
) B
WHERE 1=1
AND A.COL = B.COL
AND B.COL IS NULL
AND ~~
)
실제 쿼리는 다르게 쓰일 수 있으나
중요한 것은 조건절에
AND B.COL IS NULL
입니다.
테이블 간 조인을 걸고
존재하지 않아야 하는 컬럼을
조건절에 ~~ IS NULL을 걸면 속도가 개선됩니다.
추가로
TBL1 테이블에는 COL, ROW 2 컬럼만 존재한다는 가정하에
SELECT *
FROM TBL1 A
WHERE 1=1
AND ~~
위 코드처럼
* 을 쓰면 속도가 느려지므로
SELECT A.COL
, A.ROW
FROM TBL1 A
WHERE 1=1
로 필요한 컬럼을 직접 쓰는 것이 속도나 성능에선 더 좋습니다