아래와 같은 쿼리가 있다.
SELECT *
FROM A,
(
SELECT ...
FROM (
SELECT
FROM ...
WHERE A.COL1 = B.COL1
AND A.COL2 = B.COL2
GROUP BY ...
)
) INLINEVIEW B
WHERE A.COL1='AA' AND A.COL3 > SYSDATE -3
AND A.COL1 = B.COL1(+)
AND A.COL2 = B.COL2(+)
위 구조에서
인라인뷰 B 가 GROUP BY 등으로 가공된 집합이라면
A 의 조건들이 인라인뷰로 파고들어가지 못한다.
인라인 뷰는 기본적으로 일반테이블과 조인시 동등한 관계이기 때문
만약, 테이블 A 와 인라인 뷰가 1:1 이나 M:1 조인이라면 (조인으로 인해 결과 ROWS 가 바뀌지 않는다면)
인라인뷰를 스칼라서브쿼리로 바꿔줄수 있다.
SELECT XXX,
(
SELECT ...
FROM (
SELECT
FROM ...
WHERE A.COL1 = B.COL1
AND A.COL2 = B.COL2
GROUP BY ...
)
)
FROM A
WHERE A.COL1='AA' AND A.COL3 > SYSDATE -3
스칼라서브쿼리는 메인테이블에 종속적 관계이기 때문에 메인테이블을 참조해서 쓸수있다.
그러나, 1:1 이나 M:1 의 관계가 아니라면 쓸수 없다.
그렇다면 WITH 절을 활용해서 메인테이블을 참조할수 있게 해보자.
WITH MAIN AS (
SELECT ..
FROM A
WHERE
),
INLINEVIEW AS (
SELECT ...
FROM (
SELECT
FROM ...
WHERE MAIN.COL1 = B.COL1
AND MAIN.COL2 = B.COL2
GROUP BY ...
)
)
SELECT *
FROM MAIN A
, INLINEVIEW B
WHERE A.COL1 = B.COL1(+)
AND A.COL2 = B.COL2(+)
스칼라서브쿼리로 변경한 것보다 비효율은 존재하지만
인라인뷰가 1의 집합이 아닌경우에도 쓸수있다.
## 쿼리를 잘모르는 개발자들은 업무에 대한 쿼리를 업무요건에 따라 그때 그때 만들기보다
모듈 개념으로 여기서 쓰던 쿼리를 그대로 따오는 경향이 있다.
그런 케이스에서 위와 같은 비효율이 존재하는 쿼리가 만들어진다.
'생계 > 튜닝' 카테고리의 다른 글
rac 환경 통계수집 후 no_invalidate (0) | 2023.06.10 |
---|---|
오라클 AWR 사용하기 (0) | 2023.05.13 |
[SQL]열거된 OR 제거하기. IN 사용 (0) | 2020.11.13 |
동일패턴 추가되는 NOT IN 절 (0) | 2019.11.01 |
[SQL] 전월 증감 리포트 (0) | 2019.11.01 |