728x90
반응형

select a.사원번호, Min(a.성명), nvl(count(*), 0) 고령자수
from 사원 a, 급여 b, 가족 c
where c.사원번호(+) = b.사원번호
and c.부양여부(+) < '19940202'
and a.사원번호 = b.사원번호
and b.년월 = '19980202'
and b.기본급 >= 2000
group by a.사원번호;

================= 분석======================

1. 사원 테이블을 전체 테이블스캔 방법으로 읽어 내려간다.

2. 각각의 사원번호에 대해 급여테이블의 지급년월이 199801인 로우를 기본키로 한건씩

   (Unique Scan) 찾아 급여총액을 체크하여 만족하면

3. 해당 사원번호에 대해 가족테이블의 기본키를 이용해 범위처리(Range Scan)하여 테이블을

   읽고 생년월일을 체크한다.

4. 이 때 가족테이블에 만족하는 로우가 없어도 결과는 추출한다.

 

====> 이런 SQL문은 이런식으로 하는것이 좋다.

select /*+ ordered use_nl(x y) */ y.사원번호, y.성명, 기본급, 고령자수
from (
 select /*+ use_merge(b c) */ b.사원번호, 기본급, 고령자수
 from 급여 b,
  (select 사원번호, nvl(count(*), 0) 고령자수 from 가족 where 부양여부 < '20040202' group by 사원번호) c
 where c.사원번호(+) = b.사원번호
 and b.년월 = '10030303'
 and b.기본급 >= 200000
) x, 사원 y
where x.사원번호 = y.사원번호
================= 분석 =======================

SELECT STATEMENT  1  66  8      
  NESTED LOOPS  1  66  8      
    MERGE JOIN OUTER  1  47  7      
      SORT JOIN  1  30  3      
        TABLE ACCESS FULL 급여 1  30  1      
      SORT JOIN  5  85  5      
        VIEW  5  85  3      
          SORT GROUP BY  5  50  3      
            TABLE ACCESS FULL 가족 5  50  1      
    TABLE ACCESS BY INDEX ROWID 사원 82  1K 1      
      INDEX UNIQUE SCAN SYS_C001298 82          
1. 먼저 가족테이블의 생년월일 인덱스를 범위처리하여 만 70세 이상의 로우만 액세스하여

   사원번호로 Group by하여 내부적으로 저장한다.

2. 이번에는 급여테이블을 년월 인덱스로 범위처리하여 기본급을 체크하여 만족한 로우만

   사원번호별로 정렬하여 저정한다.

3. 주어진 조건에 비추어 볼 때 저장된 두개의 집합은 크지 않다는 것을 알 수 있다.

   이 집합들은 사원번호로 머지 된다. (Merger Outer 조인)

4. 머지된 소량의 사원번호에 대해서만 사워테이블의 기본키로 액세스한다.

   (Nested Loops Join)

728x90
반응형
블로그 이미지

nineDeveloper

안녕하세요 현직 개발자 입니다 ~ 빠르게 변화하는 세상에 뒤쳐지지 않도록 우리모두 열심히 공부합시다 ~! 개발공부는 넘나 재미있는 것~!

,