50
IT 역역역역 역역 역역역역 SQL 역역역역 1 역역 역역역역역 3 역 역역역 역역역 역역 역역역 역역역 역역역역역 .

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

  • Upload
    -

  • View
    1.054

  • Download
    8

Embed Size (px)

Citation preview

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

IT 역량강화 과정효율적인 SQL 작성방법1 주차

시스템개발 3 팀 강희동본서의 모든 이미지 출처는 생략합니다 .

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

강사소개이름 : 강희동소속 : 시스템개발 3 팀 / 베네피아 PL

DBA ?

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

문서명 작성자 학습목표DBMS 동작 원리 이해

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

DB Tuning왜 하게 되는 걸까요 ?

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

품질관리

니가만들었냐 !!

품질관리 DB 튜닝

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

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 AWHERE 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 AWHERE 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

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

튜닝 전수행시간 : 3 초

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

튜닝 후수행시간 0.01 초

Driving 전략수립부분범위 처리유도

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

수업 목표

SQL 념 잡기

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

Driving 의 중요성

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

Driving 의 중요성

TABLE1 TABLE2 TABLE3

(10000 row)

(1000 row)

(2 row)

. . .

1 A2 C3 D4 K5 M6 F7 E8 M. . . .. . . .

A 가P 나C 라H 사 . . .E 마

라 10마 20

최소 10,000 회 이상 ACCESS

TABLE3 TABLE2 TA-BLE1

(10000 row)

(2 row)

라 10마 20

(1000 row)

A 가P 나C 라S 마 . . .E 마

1 A2 C3 D4 K5 M6 F7 E8 M. . . .. . . .

최대 6 회 이하 ACCESS

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

Driving 의 중요성TABLE1 TABLE2 TABLE3

(10000 row)

(1000 row)

(2 row)

. . .

1 A2 C3 D4 K5 M6 F7 E8 M. . . .. . . .

A 가P 나C 라H 사 . . .E 마

라 10마 20

-TABLE1 을 무조건 읽어야 한다면 그 다음에 올 DRIVNING 순서를 예측- 똑같은 조건 이라면 M 이 아닌 1 부터 DRIVING

TABLE1 TABLE3 TA-BLE2

(1000 row)

(10000 row)

(2 row)

. . .

1 A2 C3 D4 K5 M6 F7 E8 M. . . .. . . .

C 10E 20

A 가P 나C 라S 마 . . .E 마

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

Driving 실습

회원 TABLE

데이터 : 20 만건PK : 회원 IDFK : 부서 ID회원상태

주문 TABLE

데이터 : 500 만건PK : 주문번호FK : 회원 ID

1. A, B 부서에 주문 내역을 추출 하라2. 주문 내역 중 신용카드로만 결제한 회원정보를 추출 하라3. 탈퇴한 회원에 주문 건수와 결제 금액을 조회 하라4. 모든 부서에 유효한 회원을 대상으로만 주문 , 결제 정보를 조회 하라

부서 TABLE

데이터 : 200 건PK : 부서 ID

결제 TABLE

데이터 : 600 만건PK : 주문 ID, 결제번호FK : 결제유형 결제금액

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

절차형 사고 버리기

Flow chart

ProgrammingScript

Schedule절차형 사고 버리기 집합 사고를 키우세요

SELECT * FROM MNS A, SKP B, SKT C WHERE A. 조건 = B. 조건 AND B. 조건 = C. 조건 AND C. 조건 = ‘1234’

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

절차형 사고 버리기

SELECT * FROM MNS A, SKP B, SKT C WHERE A. 조건 = B. 조건 AND B. 조건 = C. 조건 AND C. 조건 = ‘1234’

결과값

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

절차형 사고 버리기

2

차가공

운반단위

TAB1 TAB2

....

.

.

.

.

....

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

결과 <= 과정SQL 작성 SQL

Parsing 최적화 SQLGenera-

tor데이터 추출

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

Optimizer

select col1, col2*10, . . from account x, custommer y, transection zwhere 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 가 좋은 실행계획을 수립할 수 있도록 종합적이고 전략적인 FAC-TOR 를 부여

비절차형으로 기술해야 함 집합적으로 접근해야 함

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

Optimizer

Cost Based optimizer Rule Based optimizer

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

Optimizer

Rule Based optimizerCost Based optimizer

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

Optimizer

SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND EMPNO = '7890'

SELECT * FROM EMP WHERE ENAME LIKE 'AB%' AND JOB LIKE 'SA%'

Rulebased

Costbased

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

항상 EMPNOIndex 만 사용

INDEX merge(and_equel)

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

Optimizer

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

Optimizer

SQL Pars-ing

Optimiza-tion

Row-Source Execution

Parser OptimizerRow-SourceGenerator SQL EngineParsed

SQLExecution Plan

Row-Source

1.Query Trans-former2.Estimator3.Plan Generator

StatementPreparedState-ment

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

Optimizer

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

여기서 잠깐 !

여러분들의 속마음을 들여다 보겠습니다 .

내가 DBA 도 아닌데 이런걸 알아야되 ;;

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

역할 분담 ( 개발자 <> DBA)

개발자

DBA

쿼리작성

통계 데이터 빌드디스크 관리

디스크 관리DB Health check

인덱스 리빌드

로그관리 모니터링

세션관리DB 모델링

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

Optimizer

옵티마이져 속 마음을 들여다 보세요

어떻게든 데이터만 나오면 되지 !!

옵티마이져에게 어렵게 설명하지마세요

옵티마이져를 똥개훈련 시키지 마세요

아니 ~ 아니~아니 ~ 되오 !

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

Optimizer 부분범위 처리 예제

전체범위 VS 부분범위

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

전체범위 VS 부분범위

NO

NO

NO

YES

NO

NO

YES

NO

NO

NONO

YES

YES

TAXI인천갑니까 ?

인천

수원

TAXI

인천행

YES

YES

NO

YES

YES

TAXI수원갑니까 ?

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

전체범위 VS 부분범위

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

전체범위 VS 부분범위

2

차가공

운반단위

TAB1 TAB2

....

.

.

.

.

....

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

전체범위 VS 부분범위

INDEX SCAN

FULL SCAN

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

전체범위 VS 부분범위

전 체 범 위 처 리

2차가공

운반단위

• • • •

1차스캔

Full Range Scan 후 가공하여 Array Size 만큼 추출

부 분 범 위 처 리

2차가공

운반단위

1차스캔

조건을 만족하는 Row 수가 Ar-ray Size 에 도달되면 멈춤

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

전체범위 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부분범위처리

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

INDEX, TABLE 데이터 조회 과정

SORT 된 결과

TABLE (EMP)

EMPNO ENAME JOB7654 강감찬 부장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 EMPWHERE JOB IN (' 부장‘ ,'이사‘ )

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

부분범위 처리 예제 SORT 를 대신하는 INDEX

SELECT * FROM PRODUCT WHERE YMD = ‘151116' AND ITEM LIKE 'AB%' ORDER BY YMD, ITEM

운반단위전체스캔

IN-DEX(YMD)

TABLE

SORT

.

.

.

.

.

.

.

.

SELECT * FROM PRODUCT WHERE YMD = ‘151116' AND ITEM LIKE 'AB%'

운반단위

부분스캔

INDEX (YMD+ITEM)

TABLE

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

SORT 를 대신하는 INDEX 실습2015 년에 주문된 정보를 최신 주문일자 순으로 정렬해서 모든 데이터를 가져 오시오 . 단 , ORDER BY 를 사용하지 말고 INDEX 를 활용해서 하세요

주문 테이블 명 : OE_ORD 인덱스 명 : OE_ORD_PK ( 주문일자 )

SELECT * FROM OE_ORD

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

부분범위 처리 예제 SORT 를 대신하는 INDEX( 예제 )

21200 SORT ORDER BY21200 TABLE ACCESS BY ROWID TF_ORDER21201 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 BY42000 TABLE ACCESS BY ROWID TF_ORDER42001 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)

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

부분범위 처리 예제INDEX 만 읽고 처리

SELECT DEPT, SUM(QTY) FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT;

운반단위

INDEX (DEPT)

TABLE

• •

GROUP BY• •

SELECT DEPT, SUM(QTY). FROM PRODUCT WHERE DEPT LIKE '12%' GROUP BY DEPT;

운반단위

INDEX (DEPT+QTY)

GROUP BY

• • • •

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

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 EMPWHERE JOB IN (' 부장‘ ,'이사‘ )

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

부분범위 처리 예제 INDEX 만 읽고 처리 ( 예제 )

INDEX 정보 TF_ORD_I3 (ITEM, STATUS)

SQL> SELECT STATUS, COUNT(*) FROM TF_ORDER WHERE ITEM LIKE 'HJ%' GROUP BY STATUS

20 SORT GROUP BY36631 INDEX RANGE SCAN TF_ORD_I3

2.5 sec 20 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

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

부분범위 처리 예제MAX 처리 ( 예제 )

SELECT MAX(SEQ) + 1 FROM PRODUCT WHERE DEPT = '12300';

운반단위

INDEX (DEPT)

TABLE

• •

SORT

• • MAX(SEQ)+1

SELECT /*+ INDEX_DESC( A INDEX1) */ SEQ + 1 FROM PRODUCT A WHERE DEPT = '12300' AND ROWNUM = 1;

운반단위

INDEX (DEPT+SEQ)

SEQ + 1

Page 43: 효율적인 SQL 작성방법 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 sec1 COUNT STOPKEY1 TABLE ACCESS BY ROWID TF_ORDER2 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

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

INDEX 만 읽고 처리

가장 마지막으로 조회 된 주문 일자 정보를 가져오시오 . 주문 테이블 명 : OE_ORD 인덱스 명 : OE_ORD_PK ( 주문일자 )

SELECT /*+INDEX_DESC(A OE_ORD_PK )*/ * FROM OE_ORD AWHERE ROWNUM =1 AND ORD_DATE < ‘991231’

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

부분범위 처리 예제EXISTS 의 활용

SELECT COUNT(*) INTO :CNT FROM ITEM_TABWHERE 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

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

부분범위 처리 예제ROWNUM 의 활용

SELECT COUNT(*) INTO :CNT FROM ITEM_TABWHERE 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

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

부분범위 처리 예제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 )

부분범위

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

부분범위 처리 예제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 ;

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

핵심 포인트 !

집합적사고

Opti-mizer

부분범위처리

3 가지를 꼭 기억하세요 !

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

마무리

DBMS 는 지금도 계속 진화 중입니다 .

원리를 이해하고 흐름을 이해하세요 .