생계/튜닝

GROUP BY 로 가공되어 처리범위를 줄여주지 못하는 인라인뷰

돌고래트레이너 2019. 11. 1. 11:52

아래와 같은 쿼리가 있다. 


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의 집합이 아닌경우에도 쓸수있다. 


## 쿼리를 잘모르는 개발자들은 업무에 대한 쿼리를 업무요건에 따라 그때 그때 만들기보다

모듈 개념으로 여기서 쓰던 쿼리를 그대로 따오는 경향이 있다. 

그런 케이스에서 위와 같은 비효율이 존재하는 쿼리가 만들어진다. 

반응형