select 부서명, b.사원번호, avg_amt * decode(b.직무, 'A1', 0.12, 0.11) * 가족수
from 부서 a, 사원 b,
(select 사원번호, count(*) 가족수 from 가족 where 부양여부 = 'Y' group by 사원번호) c,
(select 사원번호, avg(기본급) avg_amt from 급여 group by 사원번호) d
where b.부서코드 = a.부서코드
and c.사원번호(+) = b.사원번호
and d.사원번호(+) = b.사원번호
and a.부서코드 = '01'
SELECT STATEMENT
MERGE JOIN OUTER
MERGE JOIN OUTER
SORT JOIN
MERGE JOIN
TABLE ACCESS BY INDEX ROWID 부서
INDEX UNIQUE SCAN SYS_C001297
FILTER
TABLE ACCESS FULL 사원
SORT JOIN
VIEW
SORT GROUP BY
TABLE ACCESS FULL 급여
SORT JOIN
VIEW
SORT GROUP BY
TABLE ACCESS FULL 가족
============= 분석 결과 =============
이 SQL은 M:M 조인이 일어나지 않는다. 두개의 인라인뷰 내에는 사원번호로 Group by
하였으므로 '사원' 테이블과 모두 1:1의 관계를 가지기 때문이다. 그러므로 2개의 인라인뷰와
사원테이블을 조인한 결과는 사원테이블과 동일한 로우 단위를 가지며 부서 테이블은 이보다
상위 집합이므로 전체를 모두 조인한 결과는 사원테이블의 로우 단위가 된다.
1. 부서테이블의 기본키를 이용해 부서테이블의 하나의 로우를 액세스한다.
2. 사원테이블에 부서코드를 첫번째로 하는 인덱스가 있다면 이 인덱스를 범위처리(Range Scan)
하면서 사원테이블의 로우들을 읽는다(인덱스가 없다면 전체 테이블 스캔)
3. 해당 부서에 대한 처리가 끝나면 이들을 사원번호 순으로 정렬시켜 내부적으로 저장한다.
4. 가족테이블 전체를 스캔하여 부양가족이 Y가 아닌 로우를 찾아 사원번호순으로 정렬하여
내부적으로 저장한다.
5. 정렬된 2개의 집합을 차례로 스캔하면서 머지하여 성공한 집합을 저장한다.
6. 이 집합을 다시 사원번호 순으로 정렬하여 저장한다.
7. 급여테이블의 년월을 첫번째로 하는 인덱스가 없다면 이 인덱스를 경유하여 급여테이블을
읽는다. (경우에 따라서는 인덱스가 있더라도 전체 테이블을 스캔할 수도 있음)
8. 액세스한 결과를 사원번호 순으로 정렬하여 저장한다.
9. 두개의 집합을 사원번호로 머지하여 결과를 추출한다.
'SQL > ORACLE' 카테고리의 다른 글
[Oracle] 오라클 힌트 사용 모음.. (0) | 2014.02.12 |
---|---|
[Oracle]실행계획 Nested Loops이냐 Sort Merge조인이냐.. (0) | 2014.02.12 |
[Oracle]인덱스(index) 확인하기 (0) | 2014.02.12 |
[Oracle] 제약조건(Constraints) 어느테이블, 어느 칼럼인지 확인하기 (0) | 2014.02.12 |
[Oracle]실행결과 보는 방법 (0) | 2014.02.12 |
[Oracle]테이블에서 칼럼 삭제 (0) | 2014.02.12 |
[Oracle] Create Index 인덱스 생성 방법 (0) | 2014.02.12 |
[Oracle]기본키(Primary key) 2개의 칼럼 (0) | 2014.02.12 |