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)
'SQL > ORACLE' 카테고리의 다른 글
[Oracle] 서브쿼리를 이용한 SQL문 Decode (0) | 2014.02.12 |
---|---|
[Oracle]오라클 함수모음 숫자, 날짜, 등등 (0) | 2014.02.12 |
[Oracle] Hint 사용 예제 (0) | 2014.02.12 |
[Oracle] 오라클 힌트 사용 모음.. (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 |