인라인뷰 결과를 뷰에 제공하는 방법
interlee 수험생

답변 채택시 : 50코아

답변 2 추천 0 조회 755 2017.05.05
안녕하세요.

아래 쿼리에서 faculty_detail은 뷰이고요, emplid 필드 조건은 상수이기 때문에 faculty_detail 뷰 안에있는 테이블들에게 제공되어 범위를 줄여주며 수행시간이 1초 미만으로 괞챦케 나옵니다.

SELECT *
  FROM faculty_detail f
 WHERE 1=1
   AND f.emplid IN ('1015350', '1002958', '1044200', '1056312')
;
fast-provider.jpg

그런데 원래 제가 추구하는 바는 위에서처럼 상수를 직접 나열하는 대신 인라인뷰를 통해 얻어진 결과를 faculty_detail 뷰내에 제공하고자 하는 것입니다. 즉,  

SELECT f.*
  FROM faculty_detail f,
       (    
        -- 아래 인라인뷰의 결과: '1015350', '1002958', '1044200', '1056312'
        SELECT emplid
          FROM ad_faculty_detail
         GROUP BY emplid, nw_parent_deptid
        HAVING COUNT(*) > 1       
       ) d       
 WHERE 1=1
   AND f.emplid = d.emplid
   ;

하지만 이렇게 하면 인라인뷰의 결과가 faculty_detail안에 필터로 제공되지 못하고 뷰는 뷰대로, 인라인뷰는 인라인뷰대로 결과를 도출한다음 해시조인을 하게 되어 수행속도가 10초가 넘습니다.
slow.jpg


첫번째 쿼리의 원리처럼 인라인뷰의 결과를 상수화하여 네스티드 루프를 통해 뷰에 인젝트되게 할 수 있는 방법은 무엇일까요?  

고수님의 한수 부탁드립니다.

수험생 
댓글 (0)
목록 답변등록
인라인뷰 결과를 뷰에 제공하는 방법
jhchoi 2017.05.11

질문자로부터 답변이 채택 되었습니다.

1. Nested Loops 조인으로 유도


   원하는대로 인라인뷰 d 집합이 먼저 Driving 되면서 Nested Loops 조인으로 faculty_detail 뷰를

   조인하는 방향으로 실행계획이 수립되지 않는다면 아래와 같이 힌트를 추가해서 테스트해보시기

   바랍니다.


   /*+ leading(d) use_nl(f) no_merge(d) */


   그래도 faculty_detail 뷰 내로 조건이 파고들지 못한다면 push_pred(f) 힌트도 추가해 보시기

   바랍니다.



2. 인라인뷰 내 쿼리 변경 필요


   인라인뷰로 FROM 절에 직접 조인을 하고자 할 때 반드시 주의해야 할 점은
   조인으로 인해 기존의 집합 레벨이 변경되지 않는지를 주의해야 합니다.


   위의 SQL로 보아서는 기존에 인라인뷰 d 를 사용하지 않고 emplid 값을 직접 상수값으로 제공할 때와
   인라인뷰 d 를 추가하여 직접 조인으로 변경했을 때 결과 집합의 레벨이 변경될 가능성이 있습니다.


   인라인뷰 내에서 ad_faculty_detail 테이블을 GROUP BY 할 때 emplid, nw_parent_deptid 두개 컬럼을

   기준으로 GROUP BY 를 하고 있어 동일한 emplid 값이 반복해서 나올 가능성이 있습니다.
   그런데 faculty_detail 뷰와 조인하는 조인 연결고리는 emplid 컬럼 하나뿐이므로
   동일한 emplid 값으로 인해 조인된 결과 데이터가 중복으로 나올 수 있습니다.


   위의 경우, FROM 절에 직접 조인으로 하고자 한다면 기존 결과 집합의 레벨이 변경되지 않도록
   인라인뷰의 결과 집합을 1집합으로 만들어주어야 합니다.


   다시 말하면, 인라인뷰 d 집합의 결과를 조인 연결고리 컬럼인 emplid 컬럼 기준으로 다시 한번

   GROUP BY 를 하거나 DISTINCT 를 사용하여 조인 연결고리 컬럼인 emplid 값을 기준으로 1집합을

   만들어줌으로써 emplid 값의 중복으로 인해 조인 결과 데이터가 뻥튀기(?) 되는 오류를 방지할

   수 있습니다.

댓글 (1)
인라인뷰 결과를 뷰에 제공하는 방법
moonsunki 2017.05.10

pushed predicate는 nl join 일때만 발생되며 hash join을 nl join으로 변경 후 테스트 부탁 드립니다.

댓글 (0)