SlideShare a Scribd company logo
1 of 50
IT역량강화 과정
효율적인 SQL작성방법
1주차
시스템개발3팀 강희동
본서의 모든 이미지 출처는 생략합니다.
강사소개
이름 : 강희동
소속 : 시스템개발3팀/ 베네피아 PL
DBA ?
문서명 작성자
학습목표
DBMS 동작 원리 이해
DB Tuning
왜 하게 되는 걸까요?
품질관리
니가
만들었냐!!
품질관리 DB 튜닝
Programming vs SQL
Programming
SQL
public int aa(int a, int b)throws Exception{
int c = 0;
if(a == b){
return a;
}else{
return b;
}
}
public String getMaxNumber(int iNum1, int iNum2)throws Exception{
return iNum1 > iNum2 ? iNum1 : iNum2;
}
SELECT *
FROM (
SELECT ROWNUM RN , A.*
FROM EMP A
WHERE ENAME LIKE ‘강%’
AND JOB <> ‘SALES’
AND (STATUS = ‘1’ OR STATUS = ‘2’)
)
WHERE RN BETWEEN 1 AND 10
SELECT *
FROM
(
SELECT ROWNUM RN , A.*
FROM EMP A
WHERE ENAME LIKE ‘강%’
AND NOT EXISTS(SELECT 1 FROM EMP B
WHERE B.EMPNO = A.EMPNO
AND JOB = ‘SALES’
AND ROWNUM = 1)
AND STATUS IN (‘1’, ‘2’)
AND ROWNUM <= 10
)
WHERE RN >= 1
튜닝 전
수행시간 : 3초
튜닝 후
수행시간 0.01 초
수업 목표
SQL 념 잡기
Driving의 중요성
Driving의 중요성
TABLE1 TABLE2 TABLE3
(10000 row)
(1000 row)
(2 row)
. . .
1 A
2 C
3 D
4 K
5 M
6 F
7 E
8 M
. . . .
. . . .
A 가
P 나
C 라
H 사
. . .
E 마
라 10
마 20
최소 10,000회 이상 ACCESS
TABLE3 TABLE2 TABLE1
(10000 row)
(2 row)
라 10
마 20
(1000 row)
A 가
P 나
C 라
S 마
. . .
E 마
1 A
2 C
3 D
4 K
5 M
6 F
7 E
8 M
. . . .
. . . .
최대 6회 이하 ACCESS
Driving의 중요성
TABLE1 TABLE2 TABLE3
(10000 row)
(1000 row)
(2 row)
. . .
1 A
2 C
3 D
4 K
5 M
6 F
7 E
8 M
. . . .
. . . .
A 가
P 나
C 라
H 사
. . .
E 마
라 10
마 20
-TABLE1을 무조건 읽어야 한다면 그 다음에 올 DRIVNING 순서를 예측
-똑같은 조건 이라면 M이 아닌 1 부터 DRIVING
TABLE1 TABLE3 TABLE2
(1000 row)
(10000 row)
(2 row)
. . .
1 A
2 C
3 D
4 K
5 M
6 F
7 E
8 M
. . . .
. . . .
C 10
E 20
A 가
P 나
C 라
S 마
. . .
E 마
Driving 실습
회원 TABLE
데이터 : 20만건
PK : 회원ID
FK : 부서ID
회원상태
주문 TABLE
데이터 : 500만건
PK : 주문번호
FK : 회원ID
1. A, B 부서에 주문 내역을 추출 하라
2. 주문 내역 중 신용카드로만 결제한 회원정보를 추출 하라
3. 탈퇴한 회원에 주문 건수와 결제 금액을 조회 하라
4. 모든 부서에 유효한 회원을 대상으로만 주문, 결제 정보를 조회 하라
부서 TABLE
데이터 : 200건
PK : 부서ID
결제 TABLE
데이터 : 600만건
PK : 주문ID,
결제번호
FK : 결제유형
결제금액
절차형 사고 버리기
SELECT *
FROM MNS A,
SKP B,
SKT C
WHERE A.조건 = B.조건
AND B.조건 = C.조건
AND C.조건 = ‘1234’
절차형 사고 버리기
SELECT *
FROM MNS A,
SKP B,
SKT C
WHERE A.조건 = B.조건
AND B.조건 = C.조건
AND C.조건 = ‘1234’
결과값
절차형 사고 버리기
2
차
가
공
운반
단위
TAB1 TAB2
.
.
.
.
.
.
.
.
.
.
.
.
결과 <= 과정
SQL 작성
SQL
Parsing
최적화
SQL
Generator
데이터
추출
Optimizer
select col1,
col2*10, . .
from account x,
custommer y,
transection z
where x.acct = z.acct
and y.cust = z.cust
and jdate = ‘130319’;
SQL OPTIMIZER
DATA Dictionary
SQL
해석
COL$
IND$
OBJ$
TAB$
VIEW$
참
조
실행
customer
transaction
account
DATA
추
출
실행
계획
작성
참
조
ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346
ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저
ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93
ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ ㅑ
ㅑㅕㅜㅑ ㅜ랸웅ㄴ
ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗㅑ야 ㅏㄴ어ㅐ
B BB JHBJB M M J ㅐㅜ ㅜㄹ울
애ㅣㅓ애럴애ㅓㄹ애 ㅐ
ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ989ㅈ돌ㅍㄴㅇㄴ
ㄴ어ㅐㅑㅓ내ㅑ
ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346
ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저
ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93
ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ
ㅑㅕㅇ ㅑㅕㅜㅑ ㅜ랸웅ㄴ
ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗ
ㅑ야 ㅏㄴ어ㅐㅑ퍼ㅐㅜ ㅜㄹ울
애ㅣㅓ애럴애ㅓㄹ애 ㅐ
ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ
결
과
 사용자는 요구만 하고 OPTIMIZER가
실행계획 수립
 수립된 실행계획에 따라 엄청난 수행
속도 차이 발생
 실행계획 제어가 어렵다.
 OPTIMIZER가 좋은 실행계획을 수립
할 수 있도록 종합적이고 전략적인
FACTOR를 부여
 비절차형으로 기술해야 함
 집합적으로 접근해야 함
Optimizer
Cost Based optimizer Rule Based optimizer
Optimizer
Rule Based optimizerCost Based optimizer
Optimizer
SELECT * FROM EMP
WHERE ENAME LIKE 'AB%'
AND EMPNO = '7890'
SELECT * FROM EMP
WHERE ENAME LIKE 'AB%'
AND JOB LIKE 'SA%'
Rule
based
Cost
based
SELECT * FROM EMP
WHERE ENAME LIKE 'AB%'
AND EMPNO = '7890'
SELECT * FROM EMP
WHERE ENAME LIKE 'AB%'
AND JOB LIKE 'SA%'
SELECT * FROM EMP
WHERE JOB = 'SALESMAN'
AND EMPNO = '7890'
나중에
생성된
Index 사용
SELECT * FROM EMP
WHERE JOB = 'SALESMAN'
AND EMPNO = '7890'
분포도에 따라
ENAME index
도 사용
INDEX merge
(and_equel),
특정 iNDEX
분포도에 따라
index 사용,
혹은 full scan
항상 EMPNO
Index만 사용
INDEX merge
(and_equel)
Optimizer
Optimizer
SQL Parsing Optimization Row-Source Execution
Parser Optimizer
Row-Source
Generator SQL EngineParsed
SQL
Execution
Plan
Row-Source
1.Query Transformer
2.Estimator
3.Plan Generator
Statement
PreparedStatement
Optimizer
여기서 잠깐!
여러분들의 속마음을 들여다 보겠습니다.
내가 DBA도 아닌데
이런걸 알아야되;;
역할 분담(개발자 <> DBA)
개발자
DBA
쿼리작성
통계 데이터 빌드
디스크 관리
디스크 관리
DB Health check
인덱스 리빌드
로그관리 모니터링
세션관리
DB 모델링
Optimizer
옵티마이져 속 마음을 들여다 보세요
어떻게든 데이터만 나오면 되지!!
옵티마이져에게 어렵게 설명하지마세요
옵티마이져를 똥개훈련 시키지 마세요
아니~ 아니~
아니~되오!
Optimizer 부분범위 처리 예제
전체범위 VS 부분범위
전체범위 VS 부분범위
NO
NO
NO
YES
NO
NO
YES
NO
NO
NO
NO
YES
YES
TAXI
인천갑니까?
인천
수원
YES
YES
NO
YES
YES
TAXI
수원갑니까?
전체범위 VS 부분범위
전체범위 VS 부분범위
2
차
가
공
운반
단위
TAB1 TAB2
.
.
.
.
.
.
.
.
.
.
.
.
전체범위 VS 부분범위
INDEX SCAN
FULL SCAN
전체범위 VS 부분범위
전 체 범 위 처 리
2
차
가
공
운반단위
•
•
•
•
1
차
스
캔
Full Range Scan 후 가공하여
Array Size 만큼 추출
부 분 범 위 처 리
2
차
가
공
운반단위
1
차
스
캔
조건을 만족하는 Row 수가 Array
Size 에 도달되면 멈춤
전체범위 VS 부분범위
SELECT * FROM CUST
SELECT * FROM CUST ORDER BY CUST_NAME
ARRAY 사이즈 도달 시
결과전송
부분범위처리
전체범위처리
SELECT * FROM CUST WHERE CUST_NAME LIKE ‘%희%’전체범위처리
SELECT * FROM CUST WHERE ROWNUM < 30부분범위처리
INDEX, TABLE 데이터 조회 과정
SORT된 결과
TABLE (EMP)
EMPNO ENAME JOB
7654 강감찬 부장
7900 류관순 과장
7689 황진이 과장
7499 이순신 차장
7934 변강쇠 부장
7844 조자룡 차장
7369 안중근 이사
7839 장보고 과장
7531 신윤복 차장
7856 홍길동 과장
7432 김유신 부장
7827 김두환 부장
INDEX (JOB)
INDEX-KEY ROWID
과장 0000A95B.0002.0001
과장 0000A95B.0005.0001
과장 0000E62E.0009.0001
과장 0000E9BE.0002.0001
부장 000062BE.0001.0001
부장 000062BE.0003.0001
부장 000093A6.0005.0001
부장 000093B2.000B.0001
이사 000069C5.0001.0001
차장 0000E9BE.0002.0001
차장 0000E9BE.0005.0001
차장 0000E9BE.000B.0001
SELECT empno, ename, job
FROM EMP
WHERE JOB IN ('부장‘,'이사‘)
부분범위 처리 예제
SORT를 대신하는 INDEX
SELECT * FROM PRODUCT
WHERE YMD = ‘151116'
AND ITEM LIKE 'AB%'
ORDER BY YMD, ITEM
운반단위
전
체
스
캔
INDEX
(YMD)
TABLE
S
O
R
T
.
.
.
.
.
.
.
.
SELECT * FROM PRODUCT
WHERE YMD = ‘151116'
AND ITEM LIKE 'AB%'
운반단위
부
분
스
캔
INDEX
(YMD+ITEM)
TABLE
SORT를 대신하는 INDEX 실습
2015년에 주문된 정보를 최신 주문일자 순으로 정렬해서
모든 데이터를 가져 오시오.
단, ORDER BY를 사용하지 말고 INDEX를 활용해서 하세요
주문 테이블 명 : OE_ORD
인덱스 명 : OE_ORD_PK (주문일자)
SELECT *
FROM OE_ORD
부분범위 처리 예제
SORT를 대신하는 INDEX(예제)
21200 SORT ORDER BY
21200 TABLE ACCESS BY ROWID TF_ORDER
21201 INDEX RANGE SCAN TF_ORD_I1
SQL> SELECT ORDDATE, CUSTNO
FROM TF_ORDER A
WHERE ORDDATE between
‘151101' and ‘151130'
ORDER BY ORDDATE DESC
5.2 sec
42000 SORT ORDER BY
42000 TABLE ACCESS BY ROWID TF_ORDER
42001 INDEX RANGE SCAN TF_ORD_I2
SQL>SELECT * FROM ( SELECT ORDDATE, CUSTNO
FROM TF_ORDER A
WHERE ORDDEPT LIKE '7%‘
ORDER BY ORDDATE DESC
)WHERE ROWNUM < 10
12.5 sec
20 INDEX RANGE SCAN DESCENDING TF_ORD_I1
SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I1) */
ORDDATE, CUSTNO
FROM TF_ORDER A
WHERE ORDDATE between
‘151101' and ‘151130'
0.01 sec
20 INDEX RANGE SCAN DESCENDING TF_ORD_I1
SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I1) */
ORDDATE, CUSTNO
FROM TF_ORDER A
WHERE ORDDEPT LIKE '7%'
AND ORDDATE <= '991231‘
AND ROWNUM < 10 0.02 sec
INDEX 정보
TF_ORD_I1(ORDDATE)
TF_ORD_I2(ORDDEPT)
부분범위 처리 예제
INDEX만 읽고 처리
SELECT DEPT, SUM(QTY)
FROM PRODUCT
WHERE DEPT LIKE '12%'
GROUP BY DEPT;
운반단위
INDEX
(DEPT)
TABLE
•
•
G
R
O
U
P
B
Y•
•
SELECT DEPT, SUM(QTY).
FROM PRODUCT
WHERE DEPT LIKE '12%'
GROUP BY DEPT;
운반단위
INDEX
(DEPT+QTY)
G
R
O
U
P
B
Y
•
•
•
•
INDEX, TABLE 데이터 조회 과정
SORT된 결과
INDEX (JOB)
INDEX-KEY ROWID
과장 0000A95B.0002.0001
과장 0000A95B.0005.0001
과장 0000E62E.0009.0001
과장 0000E9BE.0002.0001
부장 000062BE.0001.0001
부장 000062BE.0003.0001
부장 000093A6.0005.0001
부장 000093B2.000B.0001
이사 000069C5.0001.0001
차장 0000E9BE.0002.0001
차장 0000E9BE.0005.0001
차장 0000E9BE.000B.0001
SELECT JOB
FROM EMP
WHERE JOB IN ('부장‘,'이사‘)
부분범위 처리 예제
INDEX만 읽고 처리(예제)
INDEX 정보 TF_ORD_I3 (ITEM, STATUS)
SQL> SELECT STATUS, COUNT(*)
FROM TF_ORDER
WHERE ITEM LIKE 'HJ%'
GROUP BY STATUS
20 SORT GROUP BY
36631 INDEX RANGE SCAN TF_ORD_I3
2.5 sec20 SORT GROUP BY
36630 TABLE ACCESS BY ROWID TF_ORDER
36631 INDEX RANGE SCAN TF_ORD_I3
SQL> SELECT TYPE, COUNT(*)
FROM TF_ORDER
WHERE ITEM LIKE 'HJ%'
GROUP BY TYPE
10.3 sec
부분범위 처리 예제
MAX 처리(예제)
SELECT MAX(SEQ) + 1
FROM PRODUCT
WHERE DEPT = '12300';
운반단위
INDEX
(DEPT)
TABLE
•
•
S
O
R
T
•
•
MAX(SEQ)+1
SELECT /*+ INDEX_DESC( A INDEX1) */
SEQ + 1
FROM PRODUCT A
WHERE DEPT = '12300'
AND ROWNUM = 1;
운반단위
INDEX
(DEPT+SEQ)
SEQ + 1
부분범위 처리 예제
MAX 처리(예제)
INDEX 정보 TF_ORD_I4 (ORDDEPT, STATUS, ORDDATE)
SQL> SELECT MAX(ORDDATE)
FROM TF_ORDER
WHERE ORDDEPT = '430'
AND STATUS = '30'
1 SORT AGGREGATE
2892 TABLE ACCESS BY ROWID TF_ORDER
15230 INDEX RANGE SCAN TF_ORD_I4
2.53 sec
1 COUNT STOPKEY
1 TABLE ACCESS BY ROWID TF_ORDER
2 INDEX RANGE SCAN DESCENDING TF_ORD_I4
SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I4) */
ORDDATE
FROM TF_ORDER A
WHERE ORDDEPT = '430' AND STATUS='30'
AND ROWNUM = 1
0.01 sec
INDEX만 읽고 처리
가장 마지막으로 조회 된 주문 일자 정보를 가져오시오. 주문 테이블 명 : OE_ORD
인덱스 명 : OE_ORD_PK (주문일자)
SELECT
/*+INDEX_DESC(A OE_ORD_PK )*/
*
FROM OE_ORD A
WHERE ROWNUM =1
AND ORD_DATE < ‘991231’
부분범위 처리 예제
EXISTS의 활용
SELECT COUNT(*) INTO :CNT
FROM ITEM_TAB
WHERE DEPT = '101'
AND SEQ > 100
. . . . . . .
IF CNT > 0 . . .
. . . . . . .
INDEX
(DEPT)
TABLE
.
.
.
.
.
.....
운반
단위
COUNT
SELECT 1 INTO :CNT FROM DUAL
WHERE EXISTS
(SELECT 'X'
FROM ITEM_TAB
WHERE DEPT = '101'
AND SEQ > 100 )
. . . . . . .
IF CNT > 0
. . . . . . .
INDEX
(DEPT)
TABLE
운반
단위
X
O
부분범위 처리 예제
ROWNUM의 활용
SELECT COUNT(*) INTO :CNT
FROM ITEM_TAB
WHERE DEPT = '101'
AND SEQ > 100
. . . . . . .
IF CNT > 0 . . .
. . . . . . .
INDEX
(DEPT)
TABLE
.
.
.
.
.
.....
운반
단위
COUNT
SELECT 1 INTO :CNT
FROM ITEM_TAB
WHERE DEPT = '101'
AND SEQ > 100
AND ROWNUM = 1
. . . . . . . .
IF CNT > 0
. . . . . . . .
INDEX
(DEPT)
TABLE
운반
단위
X
O
부분범위 처리 예제
1:M JOIN의 부분범위 유도(EXISTS)
SELECT x.CUST_NO, x.ADDR, x.NAME, .............
FROM CUST x, REQT y
WHERE x.CUST_NO = y.CUST_NO
AND x.CUST_STAT in ('A', 'C', 'F')
AND y.UN_PAY > 0
GROUP BY x.CUST_NO
HAVING SUM(y.UN_PAY) between :VAL1 and :VAL2
전체범위
SELECT x.CUST_NO, x.ADDR, x.NAME, .............
FROM CUST x
WHERE CUST_STAT in ('A', 'C', 'F')
AND EXISTS ( SELECT 'X'
FROM REQT y
WHERE y.CUST_NO = x.CUST_NO
AND UN_PAY > 0
GROUP BY y.CUST_NO
HAVING SUM(y.UN_PAY)
between :VAL1 and :VAL2 )
부분범위
부분범위 처리 예제
1:M JOIN의 부분범위 유도(Function)
SELECT x.CUST_NO, x.ADDR, x.NAME, .............
FROM CUST x, REQT y
WHERE x.CUST_NO = y.CUST_NO
AND x.CUST_STAT in ('A', 'C', 'F')
AND y.UN_PAY > 0
GROUP BY x.CUST_NO
HAVING SUM(y.UN_PAY) between :VAL1 and :VAL2
전체범위
Select cust_no, addr, un_pay, ...........
from ( select cust_no, addr,
unpay_sum(cust_no) as un_pay,
....
from cust
where cust_stat in ('A', 'C', 'F') )
where un_pay between :VAL1 and :VAL2
부분범위Create or replace Function unpay_sum
(v_custno in varchar2)
return number is
sum_unpay number ;
begin
..............
select sum(un_pay) into sum_unpay
from reqt
where cust_no = v_custno
and un_pay > 0 ;
................
return sum_unpay ;
end unpay_sum ;
핵심 포인트!
집합적
사고
Optimizer
부분범위
처리
3가지를 꼭 기억하세요!
마무리
DBMS는 지금도 계속 진화 중입니다.

More Related Content

What's hot

What's hot (20)

Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricksQuery Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
 
Soma search
Soma searchSoma search
Soma search
 
개발자도 알아야 하는 DBMS튜닝
개발자도 알아야 하는 DBMS튜닝개발자도 알아야 하는 DBMS튜닝
개발자도 알아야 하는 DBMS튜닝
 
redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
MySQL GTID 시작하기
MySQL GTID 시작하기MySQL GTID 시작하기
MySQL GTID 시작하기
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
구름 이야기(Feat. gcp) - 구글클라우드(GCP) 활용 사례
구름 이야기(Feat. gcp) - 구글클라우드(GCP) 활용 사례구름 이야기(Feat. gcp) - 구글클라우드(GCP) 활용 사례
구름 이야기(Feat. gcp) - 구글클라우드(GCP) 활용 사례
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
 
Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기
 
OSC東京2013/Spring_JPUG資料
OSC東京2013/Spring_JPUG資料OSC東京2013/Spring_JPUG資料
OSC東京2013/Spring_JPUG資料
 
(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速する(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速する
 
Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략
 
[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning
 
PostgreSQL:行数推定を読み解く
PostgreSQL:行数推定を読み解くPostgreSQL:行数推定を読み解く
PostgreSQL:行数推定を読み解く
 
In-memory OLTP storage with persistence and transaction support
In-memory OLTP storage with persistence and transaction supportIn-memory OLTP storage with persistence and transaction support
In-memory OLTP storage with persistence and transaction support
 

Similar to 효율적인 SQL 작성방법 1주차

효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차
희동 강
 
효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차
희동 강
 
효율적인Sql작성방법 4주차
효율적인Sql작성방법 4주차효율적인Sql작성방법 4주차
효율적인Sql작성방법 4주차
희동 강
 

Similar to 효율적인 SQL 작성방법 1주차 (20)

효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차
 
효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차
 
효율적인Sql작성방법 4주차
효율적인Sql작성방법 4주차효율적인Sql작성방법 4주차
효율적인Sql작성방법 4주차
 
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
 
3.2 실행계획 sql 연산 (concatenation)
3.2 실행계획 sql 연산 (concatenation)3.2 실행계획 sql 연산 (concatenation)
3.2 실행계획 sql 연산 (concatenation)
 
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124
 
NLJ BATCH와 부분범위 처리_Wh oracle
NLJ BATCH와 부분범위 처리_Wh oracleNLJ BATCH와 부분범위 처리_Wh oracle
NLJ BATCH와 부분범위 처리_Wh oracle
 
1.9 튜닝의도구 10053 event
1.9 튜닝의도구 10053 event1.9 튜닝의도구 10053 event
1.9 튜닝의도구 10053 event
 
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
 
Federated Engine 실무적용사례
Federated Engine 실무적용사례Federated Engine 실무적용사례
Federated Engine 실무적용사례
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQL
 
(SQL초보자를 위한, 쿼리최적화 for SQL튜닝)SQL쿼리작성Tip,최적화팁,최적화된SQL작성방법교육
(SQL초보자를 위한, 쿼리최적화 for SQL튜닝)SQL쿼리작성Tip,최적화팁,최적화된SQL작성방법교육(SQL초보자를 위한, 쿼리최적화 for SQL튜닝)SQL쿼리작성Tip,최적화팁,최적화된SQL작성방법교육
(SQL초보자를 위한, 쿼리최적화 for SQL튜닝)SQL쿼리작성Tip,최적화팁,최적화된SQL작성방법교육
 
NO PARALLEL DML
NO PARALLEL DMLNO PARALLEL DML
NO PARALLEL DML
 
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracleSQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
 
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracleSPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
 
[2015-06-12] Oracle 성능 최적화 및 품질 고도화 1
[2015-06-12] Oracle 성능 최적화 및 품질 고도화 1[2015-06-12] Oracle 성능 최적화 및 품질 고도화 1
[2015-06-12] Oracle 성능 최적화 및 품질 고도화 1
 
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
 
제 7회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 7회 엑셈 수요 세미나 자료 연구컨텐츠팀제 7회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 7회 엑셈 수요 세미나 자료 연구컨텐츠팀
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
 

효율적인 SQL 작성방법 1주차

  • 1. IT역량강화 과정 효율적인 SQL작성방법 1주차 시스템개발3팀 강희동 본서의 모든 이미지 출처는 생략합니다.
  • 2. 강사소개 이름 : 강희동 소속 : 시스템개발3팀/ 베네피아 PL DBA ?
  • 4. DB Tuning 왜 하게 되는 걸까요?
  • 6. Programming vs SQL Programming SQL public int aa(int a, int b)throws Exception{ int c = 0; if(a == b){ return a; }else{ return b; } } public String getMaxNumber(int iNum1, int iNum2)throws Exception{ return iNum1 > iNum2 ? iNum1 : iNum2; } SELECT * FROM ( SELECT ROWNUM RN , A.* FROM EMP A WHERE ENAME LIKE ‘강%’ AND JOB <> ‘SALES’ AND (STATUS = ‘1’ OR STATUS = ‘2’) ) WHERE RN BETWEEN 1 AND 10 SELECT * FROM ( SELECT ROWNUM RN , A.* FROM EMP A WHERE ENAME LIKE ‘강%’ AND NOT EXISTS(SELECT 1 FROM EMP B WHERE B.EMPNO = A.EMPNO AND JOB = ‘SALES’ AND ROWNUM = 1) AND STATUS IN (‘1’, ‘2’) AND ROWNUM <= 10 ) WHERE RN >= 1
  • 11. Driving의 중요성 TABLE1 TABLE2 TABLE3 (10000 row) (1000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . A 가 P 나 C 라 H 사 . . . E 마 라 10 마 20 최소 10,000회 이상 ACCESS TABLE3 TABLE2 TABLE1 (10000 row) (2 row) 라 10 마 20 (1000 row) A 가 P 나 C 라 S 마 . . . E 마 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . 최대 6회 이하 ACCESS
  • 12. Driving의 중요성 TABLE1 TABLE2 TABLE3 (10000 row) (1000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . A 가 P 나 C 라 H 사 . . . E 마 라 10 마 20 -TABLE1을 무조건 읽어야 한다면 그 다음에 올 DRIVNING 순서를 예측 -똑같은 조건 이라면 M이 아닌 1 부터 DRIVING TABLE1 TABLE3 TABLE2 (1000 row) (10000 row) (2 row) . . . 1 A 2 C 3 D 4 K 5 M 6 F 7 E 8 M . . . . . . . . C 10 E 20 A 가 P 나 C 라 S 마 . . . E 마
  • 13. Driving 실습 회원 TABLE 데이터 : 20만건 PK : 회원ID FK : 부서ID 회원상태 주문 TABLE 데이터 : 500만건 PK : 주문번호 FK : 회원ID 1. A, B 부서에 주문 내역을 추출 하라 2. 주문 내역 중 신용카드로만 결제한 회원정보를 추출 하라 3. 탈퇴한 회원에 주문 건수와 결제 금액을 조회 하라 4. 모든 부서에 유효한 회원을 대상으로만 주문, 결제 정보를 조회 하라 부서 TABLE 데이터 : 200건 PK : 부서ID 결제 TABLE 데이터 : 600만건 PK : 주문ID, 결제번호 FK : 결제유형 결제금액
  • 14. 절차형 사고 버리기 SELECT * FROM MNS A, SKP B, SKT C WHERE A.조건 = B.조건 AND B.조건 = C.조건 AND C.조건 = ‘1234’
  • 15. 절차형 사고 버리기 SELECT * FROM MNS A, SKP B, SKT C WHERE A.조건 = B.조건 AND B.조건 = C.조건 AND C.조건 = ‘1234’ 결과값
  • 17. 결과 <= 과정 SQL 작성 SQL Parsing 최적화 SQL Generator 데이터 추출
  • 18. Optimizer select col1, col2*10, . . from account x, custommer y, transection z where x.acct = z.acct and y.cust = z.cust and jdate = ‘130319’; SQL OPTIMIZER DATA Dictionary SQL 해석 COL$ IND$ OBJ$ TAB$ VIEW$ 참 조 실행 customer transaction account DATA 추 출 실행 계획 작성 참 조 ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346 ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저 ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93 ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ ㅑ ㅑㅕㅜㅑ ㅜ랸웅ㄴ ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗㅑ야 ㅏㄴ어ㅐ B BB JHBJB M M J ㅐㅜ ㅜㄹ울 애ㅣㅓ애럴애ㅓㄹ애 ㅐ ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ989ㅈ돌ㅍㄴㅇㄴ ㄴ어ㅐㅑㅓ내ㅑ ㄴㅍㄴㅇㄹㅇㄹㄴ 률ㄷㄱ34346 ㅓㅏㄴ아ㅓㅗㄴㅇ ㅓㅜㄴ야ㄷㅈㄷㅂ저 ㅊ리아ㅡㄹ ㅏㅡ치ㅏ ㅜ ㅓ투 93 ㅑㅇ너ㅓㅇㄹ너ㅐㅇ러ㅐㄿㄹㅇㄹ ㅓㅜㄴ ㅑㅕㅇ ㅑㅕㅜㅑ ㅜ랸웅ㄴ ㅑ어ㅐ우ㅐㅇ눈애ㅓ래ㅓㅐ앵래 8ㅈ9ㅗ9 ㅗ ㅑ야 ㅏㄴ어ㅐㅑ퍼ㅐㅜ ㅜㄹ울 애ㅣㅓ애럴애ㅓㄹ애 ㅐ ㄹ앙ㄹㄹ이ㅏㅡㅈ냐ㅈㄷㅂ 결 과  사용자는 요구만 하고 OPTIMIZER가 실행계획 수립  수립된 실행계획에 따라 엄청난 수행 속도 차이 발생  실행계획 제어가 어렵다.  OPTIMIZER가 좋은 실행계획을 수립 할 수 있도록 종합적이고 전략적인 FACTOR를 부여  비절차형으로 기술해야 함  집합적으로 접근해야 함
  • 19. Optimizer Cost Based optimizer Rule Based optimizer
  • 21. Optimizer SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND EMPNO = '7890' SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND JOB LIKE 'SA%' Rule based Cost based SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND EMPNO = '7890' SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND JOB LIKE 'SA%' SELECT * FROM EMP WHERE JOB = 'SALESMAN' AND EMPNO = '7890' 나중에 생성된 Index 사용 SELECT * FROM EMP WHERE JOB = 'SALESMAN' AND EMPNO = '7890' 분포도에 따라 ENAME index 도 사용 INDEX merge (and_equel), 특정 iNDEX 분포도에 따라 index 사용, 혹은 full scan 항상 EMPNO Index만 사용 INDEX merge (and_equel)
  • 23. Optimizer SQL Parsing Optimization Row-Source Execution Parser Optimizer Row-Source Generator SQL EngineParsed SQL Execution Plan Row-Source 1.Query Transformer 2.Estimator 3.Plan Generator Statement PreparedStatement
  • 25. 여기서 잠깐! 여러분들의 속마음을 들여다 보겠습니다. 내가 DBA도 아닌데 이런걸 알아야되;;
  • 26. 역할 분담(개발자 <> DBA) 개발자 DBA 쿼리작성 통계 데이터 빌드 디스크 관리 디스크 관리 DB Health check 인덱스 리빌드 로그관리 모니터링 세션관리 DB 모델링
  • 27. Optimizer 옵티마이져 속 마음을 들여다 보세요 어떻게든 데이터만 나오면 되지!! 옵티마이져에게 어렵게 설명하지마세요 옵티마이져를 똥개훈련 시키지 마세요 아니~ 아니~ 아니~되오!
  • 28. Optimizer 부분범위 처리 예제 전체범위 VS 부분범위
  • 33. 전체범위 VS 부분범위 전 체 범 위 처 리 2 차 가 공 운반단위 • • • • 1 차 스 캔 Full Range Scan 후 가공하여 Array Size 만큼 추출 부 분 범 위 처 리 2 차 가 공 운반단위 1 차 스 캔 조건을 만족하는 Row 수가 Array Size 에 도달되면 멈춤
  • 34. 전체범위 VS 부분범위 SELECT * FROM CUST SELECT * FROM CUST ORDER BY CUST_NAME ARRAY 사이즈 도달 시 결과전송 부분범위처리 전체범위처리 SELECT * FROM CUST WHERE CUST_NAME LIKE ‘%희%’전체범위처리 SELECT * FROM CUST WHERE ROWNUM < 30부분범위처리
  • 35. INDEX, TABLE 데이터 조회 과정 SORT된 결과 TABLE (EMP) EMPNO ENAME JOB 7654 강감찬 부장 7900 류관순 과장 7689 황진이 과장 7499 이순신 차장 7934 변강쇠 부장 7844 조자룡 차장 7369 안중근 이사 7839 장보고 과장 7531 신윤복 차장 7856 홍길동 과장 7432 김유신 부장 7827 김두환 부장 INDEX (JOB) INDEX-KEY ROWID 과장 0000A95B.0002.0001 과장 0000A95B.0005.0001 과장 0000E62E.0009.0001 과장 0000E9BE.0002.0001 부장 000062BE.0001.0001 부장 000062BE.0003.0001 부장 000093A6.0005.0001 부장 000093B2.000B.0001 이사 000069C5.0001.0001 차장 0000E9BE.0002.0001 차장 0000E9BE.0005.0001 차장 0000E9BE.000B.0001 SELECT empno, ename, job FROM EMP WHERE JOB IN ('부장‘,'이사‘)
  • 36. 부분범위 처리 예제 SORT를 대신하는 INDEX SELECT * FROM PRODUCT WHERE YMD = ‘151116' AND ITEM LIKE 'AB%' ORDER BY YMD, ITEM 운반단위 전 체 스 캔 INDEX (YMD) TABLE S O R T . . . . . . . . SELECT * FROM PRODUCT WHERE YMD = ‘151116' AND ITEM LIKE 'AB%' 운반단위 부 분 스 캔 INDEX (YMD+ITEM) TABLE
  • 37. SORT를 대신하는 INDEX 실습 2015년에 주문된 정보를 최신 주문일자 순으로 정렬해서 모든 데이터를 가져 오시오. 단, ORDER BY를 사용하지 말고 INDEX를 활용해서 하세요 주문 테이블 명 : OE_ORD 인덱스 명 : OE_ORD_PK (주문일자) SELECT * FROM OE_ORD
  • 38. 부분범위 처리 예제 SORT를 대신하는 INDEX(예제) 21200 SORT ORDER BY 21200 TABLE ACCESS BY ROWID TF_ORDER 21201 INDEX RANGE SCAN TF_ORD_I1 SQL> SELECT ORDDATE, CUSTNO FROM TF_ORDER A WHERE ORDDATE between ‘151101' and ‘151130' ORDER BY ORDDATE DESC 5.2 sec 42000 SORT ORDER BY 42000 TABLE ACCESS BY ROWID TF_ORDER 42001 INDEX RANGE SCAN TF_ORD_I2 SQL>SELECT * FROM ( SELECT ORDDATE, CUSTNO FROM TF_ORDER A WHERE ORDDEPT LIKE '7%‘ ORDER BY ORDDATE DESC )WHERE ROWNUM < 10 12.5 sec 20 INDEX RANGE SCAN DESCENDING TF_ORD_I1 SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I1) */ ORDDATE, CUSTNO FROM TF_ORDER A WHERE ORDDATE between ‘151101' and ‘151130' 0.01 sec 20 INDEX RANGE SCAN DESCENDING TF_ORD_I1 SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I1) */ ORDDATE, CUSTNO FROM TF_ORDER A WHERE ORDDEPT LIKE '7%' AND ORDDATE <= '991231‘ AND ROWNUM < 10 0.02 sec INDEX 정보 TF_ORD_I1(ORDDATE) TF_ORD_I2(ORDDEPT)
  • 39. 부분범위 처리 예제 INDEX만 읽고 처리 SELECT DEPT, SUM(QTY) FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT; 운반단위 INDEX (DEPT) TABLE • • G R O U P B Y• • SELECT DEPT, SUM(QTY). FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT; 운반단위 INDEX (DEPT+QTY) G R O U P B Y • • • •
  • 40. INDEX, TABLE 데이터 조회 과정 SORT된 결과 INDEX (JOB) INDEX-KEY ROWID 과장 0000A95B.0002.0001 과장 0000A95B.0005.0001 과장 0000E62E.0009.0001 과장 0000E9BE.0002.0001 부장 000062BE.0001.0001 부장 000062BE.0003.0001 부장 000093A6.0005.0001 부장 000093B2.000B.0001 이사 000069C5.0001.0001 차장 0000E9BE.0002.0001 차장 0000E9BE.0005.0001 차장 0000E9BE.000B.0001 SELECT JOB FROM EMP WHERE JOB IN ('부장‘,'이사‘)
  • 41. 부분범위 처리 예제 INDEX만 읽고 처리(예제) INDEX 정보 TF_ORD_I3 (ITEM, STATUS) SQL> SELECT STATUS, COUNT(*) FROM TF_ORDER WHERE ITEM LIKE 'HJ%' GROUP BY STATUS 20 SORT GROUP BY 36631 INDEX RANGE SCAN TF_ORD_I3 2.5 sec20 SORT GROUP BY 36630 TABLE ACCESS BY ROWID TF_ORDER 36631 INDEX RANGE SCAN TF_ORD_I3 SQL> SELECT TYPE, COUNT(*) FROM TF_ORDER WHERE ITEM LIKE 'HJ%' GROUP BY TYPE 10.3 sec
  • 42. 부분범위 처리 예제 MAX 처리(예제) SELECT MAX(SEQ) + 1 FROM PRODUCT WHERE DEPT = '12300'; 운반단위 INDEX (DEPT) TABLE • • S O R T • • MAX(SEQ)+1 SELECT /*+ INDEX_DESC( A INDEX1) */ SEQ + 1 FROM PRODUCT A WHERE DEPT = '12300' AND ROWNUM = 1; 운반단위 INDEX (DEPT+SEQ) SEQ + 1
  • 43. 부분범위 처리 예제 MAX 처리(예제) INDEX 정보 TF_ORD_I4 (ORDDEPT, STATUS, ORDDATE) SQL> SELECT MAX(ORDDATE) FROM TF_ORDER WHERE ORDDEPT = '430' AND STATUS = '30' 1 SORT AGGREGATE 2892 TABLE ACCESS BY ROWID TF_ORDER 15230 INDEX RANGE SCAN TF_ORD_I4 2.53 sec 1 COUNT STOPKEY 1 TABLE ACCESS BY ROWID TF_ORDER 2 INDEX RANGE SCAN DESCENDING TF_ORD_I4 SQL> SELECT /*+ INDEX_DESC(A TF_ORD_I4) */ ORDDATE FROM TF_ORDER A WHERE ORDDEPT = '430' AND STATUS='30' AND ROWNUM = 1 0.01 sec
  • 44. INDEX만 읽고 처리 가장 마지막으로 조회 된 주문 일자 정보를 가져오시오. 주문 테이블 명 : OE_ORD 인덱스 명 : OE_ORD_PK (주문일자) SELECT /*+INDEX_DESC(A OE_ORD_PK )*/ * FROM OE_ORD A WHERE ROWNUM =1 AND ORD_DATE < ‘991231’
  • 45. 부분범위 처리 예제 EXISTS의 활용 SELECT COUNT(*) INTO :CNT FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 . . . . . . . IF CNT > 0 . . . . . . . . . . INDEX (DEPT) TABLE . . . . . ..... 운반 단위 COUNT SELECT 1 INTO :CNT FROM DUAL WHERE EXISTS (SELECT 'X' FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 ) . . . . . . . IF CNT > 0 . . . . . . . INDEX (DEPT) TABLE 운반 단위 X O
  • 46. 부분범위 처리 예제 ROWNUM의 활용 SELECT COUNT(*) INTO :CNT FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 . . . . . . . IF CNT > 0 . . . . . . . . . . INDEX (DEPT) TABLE . . . . . ..... 운반 단위 COUNT SELECT 1 INTO :CNT FROM ITEM_TAB WHERE DEPT = '101' AND SEQ > 100 AND ROWNUM = 1 . . . . . . . . IF CNT > 0 . . . . . . . . INDEX (DEPT) TABLE 운반 단위 X O
  • 47. 부분범위 처리 예제 1:M JOIN의 부분범위 유도(EXISTS) SELECT x.CUST_NO, x.ADDR, x.NAME, ............. FROM CUST x, REQT y WHERE x.CUST_NO = y.CUST_NO AND x.CUST_STAT in ('A', 'C', 'F') AND y.UN_PAY > 0 GROUP BY x.CUST_NO HAVING SUM(y.UN_PAY) between :VAL1 and :VAL2 전체범위 SELECT x.CUST_NO, x.ADDR, x.NAME, ............. FROM CUST x WHERE CUST_STAT in ('A', 'C', 'F') AND EXISTS ( SELECT 'X' FROM REQT y WHERE y.CUST_NO = x.CUST_NO AND UN_PAY > 0 GROUP BY y.CUST_NO HAVING SUM(y.UN_PAY) between :VAL1 and :VAL2 ) 부분범위
  • 48. 부분범위 처리 예제 1:M JOIN의 부분범위 유도(Function) SELECT x.CUST_NO, x.ADDR, x.NAME, ............. FROM CUST x, REQT y WHERE x.CUST_NO = y.CUST_NO AND x.CUST_STAT in ('A', 'C', 'F') AND y.UN_PAY > 0 GROUP BY x.CUST_NO HAVING SUM(y.UN_PAY) between :VAL1 and :VAL2 전체범위 Select cust_no, addr, un_pay, ........... from ( select cust_no, addr, unpay_sum(cust_no) as un_pay, .... from cust where cust_stat in ('A', 'C', 'F') ) where un_pay between :VAL1 and :VAL2 부분범위Create or replace Function unpay_sum (v_custno in varchar2) return number is sum_unpay number ; begin .............. select sum(un_pay) into sum_unpay from reqt where cust_no = v_custno and un_pay > 0 ; ................ return sum_unpay ; end unpay_sum ;
  • 50. 마무리 DBMS는 지금도 계속 진화 중입니다.

Editor's Notes

  1. 슬라이드 시작에 앞서 동기부여를 위한 설명 페이지번호 추가 목차 추가
  2. Statement, prestatement 바인딩 단점을 보완한 바인딩변수 peeking : 하드파싱 시 컬럼분포도를 이용해 통계정보를 만들어낸다 -SQL 파서가 파싱 반복사용하기 위해 라이브러리 캐쉬에 저장( 커서 공유) -최적화하기 쉬운형태로 변환 후보군이 될만한 실행계획들 생성 오브젝트 통계정보, 시스템 성능 통계정보를 이용하여 필요한 I/O, CPU, 메모리 사용량 등을 예측 -SQL 실행계획 생성