SELECT min(t2.상품명) 상품명,
sum(t1.판매수량) 판매수량,
sum(t1.판매금액) 판매금액
FROM 일별상품판매 t1,
상품 t2
WHERE t1.판매일자 BETWEEN '20090101' AND '20091231'
AND t1.상품코드 = t2.상품코드
GROUP BY t2.상품코드
Call Count CPU Time Elapsed Time Disk Query Current Rows
---- ---- ------- --------- ---- ---- ---- ----
Parse 1 0.000 0.000 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 101 5.109 13.805 52744 782160 0 1000
---- ---- ------- --------- ---- ---- ---- ----
Total 103 5.109 13.805 52744 782160 0 1000
Rows Row Source Operation
----- ---------------------------------------------------
1000 SORT GROUP BY (cr=782160 pr=52744 pw=0 time=13804391 us)
365000 NESTED LOOPS (cr=782160 pr=52744 pw=0 time=2734163731004 us)
365000 TABLE ACCESS FULL 일별상품판매 (cr=52158 pr=51800 pw=0 time=456175026878 us)
365000 TABLE ACCESS BY INDEX ROWID 상품 (cr=730002 pr=944 pw=0 time=872397482545 us)
365000 INDEX UNIQUE SCAN 상품_PK (cr=365002 pr=4 pw=0 time=416615350685 us)
SELECT t2.상품명,
t1.판매수량,
t1.판매금액
FROM
(SELECT 상품코드,
sum(판매수량) 판매수량,
sum(판매금액) 판매금액
FROM 일별상품판매
WHERE 판매일자 BETWEEN '20090101' AND '20091231'
GROUP BY 상품코드
) t1,
상품 t2
WHERE t1.상품코드 = t2.상품코드
Call Count CPU Time Elapsed Time Disk Query Current Rows
---- ---- ------- --------- ---- ---- ---- ----
Parse 1 0.000 0.000 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 101 1.422 5.540 51339 54259 0 1000
---- ---- ------- --------- ---- ---- ---- ----
Total 103 1.422 5.540 51339 54259 0 1000
Rows Row Source Operation
----- ---------------------------------------------------
1000 NESTED LOOPS (cr=54259 pr=51339 pw=0 time=5540320 us)
1000 VIEW (cr=52158 pr=51339 pw=0 time=5531294 us)
1000 SORT GROUP BY (cr=52158 pr=51339 pw=0 time=5530293 us)
365000 TABLE ACCESS FULL 일별상품판매 (cr=52158 pr=51339 pw=0 time=2920041 us)
1000 TABLE ACCESS BY INDEX ROWID 상품 (cr=2101 pr=0 pw=0 time=8337 us)
1000 INDEX UNIQUE SCAN 상품_PK (cr=1101 pr=0 pw=0 time=3747 us)
SELECT
/*+ ordered use_nl(b) use_nl(c) */
a.작업일련번호,
a.작업자ID,
a.작업상태코드 ,
nvl(b.고객번호, c.고객번호) 고객번호 ,
nvl(b.주소, c.주소) 주소,
......
FROM 작업지시 a,
개통신청 b,
장애접수 c
WHERE a.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
AND b.개통신청번호(+) = a.개통신청번호
AND c.장애접수번호(+) = a.장애접수번호
SELECT a.작업일련번호,
a.작업자ID,
a.작업상태코드 ,
isnull(b.고객번호, c.고객번호) 고객번호 ,
isnull(b.주소, c.주소) 주소,
......
FROM 작업지시 a
LEFT OUTER JOIN 개통신청 b ON b.개통신청번호 = a.개통신청번호
LEFT OUTER JOIN 장애접수 c ON c.장애접수번호 = a.장애접수번호
WHERE a.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
OPTION(FORCE ORDER, loop JOIN)
②번처럼 설계했을 경우는 UNION ALL을 이용한다.
SELECT x.작업일련번호,
x.작업자ID,
x.작업상태코드,
y.고객번호,
y.주소,
......
FROM 작업지시 x, 개통신청 y
WHERE x.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
AND x.작업구분 = '1'
AND y.개통신청번호 = x.접수번호
UNION ALL
SELECT x.작업일련번호,
x.작업자ID,
x.작업상태코드,
y.고객번호,
y.주소,
......
FROM 작업지시 x, 장애접수 y
WHERE x.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
AND x.작업구분 = '2'
AND y.장애접수번호 = x.접수번호
이럴 경우 아래와 같이 수정함으로써 중복 액세스에 의한 비효율 해소
SELECT
/*+ ordered use_nl(b) use_nl(c) */
a.작업일련번호,
a.작업자ID,
a.작업상태코드 ,
nvl(b.고객번호, c.고객번호) 고객번호 ,
nvl(b.주소, c.주소) 주소,
......
FROM 작업지시 a,
개통신청 b,
장애접수 c
WHERE a.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
AND b.개통신청번호(+) = decode(a.작업구분, '1', a.접수번호)
AND c.장애접수번호(+) = decode(a.작업구분, '2', a.접수번호)
SELECT a.작업일련번호, a.작업자ID, a.작업상태코드 ,
isnull(b.고객번호, c.고객번호) 고객번호 ,
isnull(b.주소, c.주소) 주소,
......
FROM 작업지시 a
LEFT OUTER JOIN 개통신청 b
ON b.개통신청번호 =
(
CASE WHEN a.작업구분 = '1' THEN a.접수번호 END
)
LEFT OUTER JOIN 장애접수 c
ON c.장애접수번호 =
(
CASE WHEN a.작업구분 = '2' THEN a.접수번호 END
)
WHERE a.방문예정일시 BETWEEN :방문예정일시1 AND :방문예정일시2
OPTION(FORCE ORDER, loop JOIN)
SELECT 지점,
판매월,
매출 ,
sum(매출) over (partition BY 지점 ORDER BY 판매월 range
BETWEEN unbounded preceding AND CURRENT ROW) 누적매출
FROM 월별지점매출
SELECT t1.지점, t1.판매월, min(t1.매출) 매출, sum(t2.매출) 누적매출
FROM 월별지점매출 t1, 월별지점매출 t2
WHERE t2.지점 = t1.지점
AND t2.판매월 <= t1.판매월
GROUP BY t1.지점, t1.판매월
ORDER BY t1.지점, t1.판매월;
<그림 Ⅲ-4-33>은 <표 Ⅲ-4-3>에 있는 123번 고객에 대한 3개의 선분이력 레코드를 일직선 상에 펼쳐서 그려본 것이다.
SELECT 고객번호,
연체금액,
연체개월수
FROM 고객별연체금액
WHERE 고객번호 = '123'
AND '20040815' BETWEEN b.시작일자 AND b.종료일자;
SELECT 고객번호,
연체금액,
연체개월수
FROM 고객별연체금액 a
WHERE 고객번호 = '123'
AND 연체변경일자 =
(SELECT max(연체변경일자)
FROM 고객별연체금액
WHERE 고객번호 = a.고객번호
AND 변경일자 <= '20040815'
) ;
SELECT 연체개월수,
연체금액
FROM 고객별연체금액
WHERE 고객번호 = :cust_num
AND :dt BETWEEN 시작일자 AND 종료일자
SELECT 연체개월수,
연체금액
FROM 고객별연체금액
WHERE 고객번호 = :cust_num
AND 종료일자 = '99991231'
SELECT c.고객번호,
c.고객명,
c1.고객등급,
c2.전화번호
FROM 고객 c,
고객등급변경이력 c1,
전화번호변경이력 c2
WHERE c.고객번호 = :cust_num
AND c1.고객번호 = c.고객번호
AND c2.고객번호 = c.고객번호
AND :dt BETWEEN c1.시작일자 AND c1.종료일자
AND :dt BETWEEN c2.시작일자 AND c2.종료일자
SELECT c.고객번호,
c.고객명,
c1.고객등급,
c2.전화번호
FROM 고객 c,
고객등급변경이력 c1,
전화번호변경이력 c2
WHERE c.고객번호 = :cust_num
AND c1.고객번호 = c.고객번호
AND c2.고객번호 = c.고객번호
AND c1.종료일자 = '99991231'
AND c2.종료일자 = '99991231'
SELECT c.고객번호,
c.고객명,
c1.고객등급,
c2.전화번호
FROM 고객 c,
고객등급변경이력 c1,
전화번호변경이력 c2
WHERE c.고객번호 = :cust_num
AND c1.고객번호 = c.고객번호
AND c2.고객번호 = c.고객번호
AND to_char(sysdate, 'yyyymmdd') BETWEEN c1.시작일자 AND c1.종료일자
AND to_char(sysdate, 'yyyymmdd') BETWEEN c2.시작일자 AND c2.종료일자
......
and convert(varchar(8), getdate(), 112) between c1.시작일자 and c1.종료일자
and convert(varchar(8), getdate(), 112) between c2.시작일자 and c2.종료일자
SELECT a.거래일자, a.종목코드, b.종목한글명, b.종목영문명, b.상장주식수 ,
a.시가, a.종가, a.체결건수, a.체결수량, a.거래대금
FROM 일별종목거래및시세 a,
종목이력 b
WHERE a.거래일자 BETWEEN to_char(add_months(sysdate, -20*12), 'yyyymmdd') AND to_char(sysdate-1, 'yyyymmdd')
AND a.종가 = a.최고가
AND b.종목코드 = a.종목코드
AND a.거래일자 BETWEEN b.시작일자 AND b.종료일자
SELECT a.거래일자, a.종목코드, b.종목한글명, b.종목영문명, b.상장주식수 ,
a.시가, a.종가, a.체결건수, a.체결수량, a.거래대금
FROM 일별종목거래및시세 a,
종목이력 b
WHERE a.거래일자 BETWEEN to_char(add_months(sysdate, -20*12), 'yyyymmdd') AND to_char(sysdate-1, 'yyyymmdd')
AND a.종가 = a.최고가
AND b.종목코드 = a.종목코드
AND to_char(sysdate, 'yyyymmdd') BETWEEN b.시작일자 AND b.종료일자
SELECT a.고객명,
a.거주지역,
a.주소,
a.연락처,
b.연체금액,
b.연체개월수
FROM 고객 a,
고객별연체이력 b
WHERE a.가입회사 = 'C70'
AND b.고객번호 = a.고객번호
AND b.변경일자 =
(SELECT max(변경일자)
FROM 고객별연체이력
WHERE 고객번호 = a.고객번호
AND 변경일자 <= a.서비스만료일
)
Execution Plan
-------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=845 Card=10 Bytes=600)
1 0 TABLE ACCESS (BY INDEX ROWID) OF '고객별연체이력' (Cost=2 Card=1 Bytes=19)
2 1 NESTED LOOPS (Cost=845 Card=10 Bytes=600)
3 2 TABLE ACCESS (BY INDEX ROWID) OF '고객' (Cost=825 Card=10 Bytes=410)
4 3 INDEX (RANGE SCAN) OF '고객_IDX01' (NON-UNIQUE) (Cost=25 Card=10)
5 2 INDEX (RANGE SCAN) OF '고객별연체이력_IDX01' (NON-UNIQUE) (Cost=1 Card=1)
6 5 SORT (AGGREGATE) (Card=1 Bytes=13)
7 6 FIRST ROW (Cost=2 Card=5K Bytes=63K)
8 7 INDEX (RANGE SCAN (MIN/MAX)) OF '고객별연체이력_IDX01' (NON-UNIQUE) (... )
SELECT
/*+ ordered use_nl(b) rowid(b) */
a.고객명,
a.거주지역,
a.주소,
a.연락처,
b.연체금액,
b.연체개월수
FROM 고객 a, 고객별연체이력 b
WHERE a.가입회사 = 'C70'
AND b.rowid =
(SELECT
/*+ index_desc(c 고객별연체이력_idx01) */
rowid
FROM 고객별연체이력 c
WHERE c.고객번호 = a.고객번호
AND c.변경일자 <= a.서비스만료일
AND ROWNUM <= 1
)
Execution Plan
-------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=835 Card=100K Bytes=5M)
1 0 NESTED LOOPS (Cost=835 Card=100K Bytes=5M)
2 1 TABLE ACCESS (BY INDEX ROWID) OF '고객' (Cost=825 Card=10 Bytes=410)
3 2 INDEX (RANGE SCAN) OF '고객_IDX01' (NON-UNIQUE) (Cost=25 Card=10)
4 1 TABLE ACCESS (BY USER ROWID) OF '고객별연체이력' (Cost=1 Card=10K Bytes=137K)
5 4 COUNT (STOPKEY)
6 5 INDEX (RANGE SCAN DESCENDING) OF '고객별연체이력_IDX01' (NON-UNIQUE) (Cost=2 Card=5K... )
- 강좌 URL : http://www.gurubee.net/lecture/2406
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.