SlideShare a Scribd company logo
1 of 75
본서의 모든 이미지 출처는 생략합니다.
IT역량강화 과정
효율적인SQL작성방법
4주차
시스템개발3팀 강희동
3주차 Review
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
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
전체범위 VS 부분범위
전 체 범 위 처 리
2
차
가
공
운반단위
•
•
•
•
1
차
스
캔
Full Range Scan 후 가공하여
Array Size 만큼 추출
부 분 범 위 처 리
2
차
가
공
운반단위
1
차
스
캔
조건을 만족하는 Row 수가 Array
Size 에 도달되면 멈춤
전체범위 VS 부분범위
INDEX SCAN
FULL SCAN
RANDOM ACCESS
운반
단위
INDEX
(FLD)
.....
2
차
가
공
TAB TAB
운반
단위
o
x
o
o
o
x
o
x
.....
x
x
2
차
가
공
o
o
Index Range Scan Full Table Scan
RANDOM ACCESS가 많이 발생되면 I/O효율이 떨어집니다.
INDEX의 중요성!
테이블 드라이빙 우선순위
부서 테이블(100건)
부서번호 (PK)
사원 테이블(10만건)
사원번호 (PK)
부서번호(FK)
①
②
조건
-부서테이블, 사원테이블에는 PK 인덱스만 존재
-전체 데이터 검색
문제
1번 테이블이 먼저 드라이빙 하는게 유리할까요?
2번 테이블이 먼저 드라이빙 하는게 유리할까요?
-1번 테이블이 먼저 드라이빙 될 경우
부서 테이블을 100건을 스캔하고서
사원 테이블을 10만번 스캔
100 X 100,000 = 1,000,000 (백만번 스캔!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
-2번 테이블이 먼저 드라이빙 될 경우
사원테이블을 10만번 스캔하고서
부서 테이블을 스캔하는데
부서번호키가 Unique index 이기 때문에 1번만 읽고 스캔
100,000 X 1 = 100,000 (십만번 스캔)
INDEX 손익분기점
가정
전체 10,000 row
1 block당 평균 10 row
전체 1,000 block
운반
단위
INDEX
(FLD)
.....
2
차
가
공
TAB TAB
운반
단위
o
x
o
o
o
x
o
x
.....
x
x
2
차
가
공
o
o
Index Range Scan Full Table Scan
 1,000 row read를
위해 1,000 block
access
 낮은 Hit Ratio
 10,000 row read를
위해 1,000 block
access
 높은 Hit Ratio
인덱스 사용여부 고려사항
Scan 범위
Hit Ratio
Clustering Factor
손익
분기점
(10 ~15%)
INDEX SCAN, FULL SCAN SWITCH
NULL 이럴 때만 사용 합시다!
-미 확정 값을 표현하고자 할 때
-결합인덱스의 구성 컬럼이 된다면 NOT NULL!
-인덱스 조건 값으로 자주 사용 된다면 NOT NULL!
특정 값이 지나치게 많고 나머지 값만 주로 인덱스로 액세스
A사
B사
C사
D사
E사
F사
B
컬럼 값
C
D
E
F
NULL TABLE FULL SCAN
INDEX RANGE SCAN
INDEX SCAN, FULL SCAN SWITCH
(78%)
4% 6% 7%
5%
A
BC D
E
COL1 분포도
KEY COL1 . . . .
TABLE1
(10000 row)
CREATE INDEX index_name ON
table_name (COL1);
COL1 = 'A' 를 그대로
COL1KEY . . . .
A. . . . . . . .
A. . . . . . . .
A. . . . . . . .
B. . . . . . . .
B. . . . . . . .
. . . .. . . . . . . .
COL1 ROWID
A . . . .
A . . . .
A . . . .
B . . . .
B . . . .
. . . . . . . .
TABLE1
(10000 row)
INDEX1
(10000 row)
COL1 = 'A' 를 COL1 NULL로
COL1KEY . . . .
Null. . . . . . . .
Null. . . . . . . .
Null. . . . . . . .
B. . . . . . . .
B. . . . . . . .
. . . .. . . . . . . .
COL1 ROWID
B . . . .
. . . . . . . .
C . . . .
. . . . . . . .
TABLE1
(10000 row)
INDEX1
(2000 row)

INDEX 컬럼의 변형
SELECT *
FROM EMP
WHERE SUBSTR(DNAME,1,3) = 'ABC'
SELECT *
FROM EMP
WHERE DNAME LIKE 'ABC%'
SELECT *
FROM EMP
WHERE SAL * 12 = 12000000
SELECT *
FROM EMP
WHERE TO_CHAR(HIREDATE,'YYMMDD')
= ‘130712'
SELECT *
FROM EMP
WHERE HIREDATE =
TO_DATE(‘130712','YYMMDD')
SELECT *
FROM EMP
WHERE SAL = 12000000 / 12
SELECT *
FROM EMP
WHERE DEPTNO || JOB = '10SALESMAN'
SELECT *
FROM EMP
WHERE DEPTNO = '10'
AND JOB = 'SALSMAN'
INDEX 컬럼의 변형
SELECT *
FROM EMP
WHERE NVL(COMM,0) < 100
?
SELECT *
FROM EMP
WHERE COMM < 100
SELECT *
FROM EMP
WHERE EMPNO BETWEEN 100 AND 200
AND NVL(JOB,'X') = 'CLERK'
SELECT *
FROM EMP
WHERE EMPNO BETWEEN 100 AND 200
AND JOB = 'CLERK'
컬럼 값에 NULL이 존재하는 경우
해결방안 : NULL 값 0으로 변경
INDEX 컬럼의 변형
SELECT *
FROM EMP
WHERE JOB = 'MANAGER'
SELECT *
FROM EMP
WHERE RTRIM(JOB) = 'MANAGER'
SELECT *
FROM EMP
WHERE EMPNO = 8978
SELECT *
FROM EMP
WHERE RTRIM(EMPNO) = 8978
SELECT CUSTNO, CHULDATE
FROM CHULGOT
WHERE CUSTNO LIKE 'DN%'
AND RTRIM(STATUS) LIKE '9%'
SELECT CUSTNO, CHULDATE
FROM CHULGOT
WHERE CUSTNO LIKE 'DN%'
AND STATUS LIKE '9%'
의도적인 SUPPRESSING
INDEX 컬럼의 변형
의도적인 SUPPRESSING
SELECT X.CUSTNO, CHULDATE, CUSTNAME
FROM MECHUL1T X, MECHUL2T Y
WHERE X.SALENO = Y.SALENO
AND X.SALEDEPT = '710'
AND Y.SALEDATE LIKE ‘1301%'
10 Sec
SELECT X.CUSTNO, CHULDATE, CUSTNAME
FROM MECHUL1T X, MECHUL2T Y
WHERE X.SALENO = Y.SALENO
AND RTRIM(X.SALEDEPT) = '710'
AND Y.SALEDATE LIKE ‘1301%'
1 Sec
SELECT X.ORDNO, ORDDATE, ITEM
FROM ORDER1T X, ORDER2T Y
WHERE X.ORDNO = Y.ORDNO
AND X.ORDDATE LIKE ‘1301%'
AND Y.ORDDEPT = '710'
ORDER BY ORDDATE
13 Sec
SELECT X.ORDNO, ORDDATE, ITEM
FROM ORDER1T X, ORDER2T Y
WHERE RTRIM(X.ORDNO) = Y.ORDNO
AND X.ORDDATE LIKE ‘1301%'
AND Y.ORDDEPT = '710’
1 Sec
연결고리 확인! 인덱스가 없으면 없는 쪽부터 드라이빙!!(중요!)
INDEX 컬럼의 변형
SELECT * FROM SAMPLET
WHERE NUM LIKE '9410%'
CREATE TABLE SAMPLET
( CHR VARCHAR2(10),
NUM NUMBER (12,3),
VAR VARCHAR2(20),
DAT DATE)
SELECT * FROM SAMPLET
WHERE CHA = 10
SELECT * FROM SAMPLET
WHERE TO_NUMBER(CHA) = 10
SELECT * FROM SAMPLET
WHERE TO_CHAR(NUM) LIKE '9410%'
SELECT * FROM SAMPLET
WHERE DAT = '01-JAN-94'
SELECT * FROM SAMPLET
WHERE DAT = TO_DATE('01-JAN-94')
DATA TYPE의 변형
INDEX 컬럼의 변형
DATA TYPE의 변형
TABLE ACCESS FULL CHULGOT
1 row,
28.5 sec
SQL> SELECT SUM(UNCOST)
FROM CHULGOT
WHERE STATUS = 90
SORT AGGREGATE
TABLE ACCESS BY ROWID CHULGOT
INDEX RANGE SCAN CH_STATUS
1 row,
0.15 sec
SQL> SELECT SUM(UNCOST)
FROM CHULGOT
WHERE STATUS = '90'
SQL> SELECT CHULNO, CUSTNO, UNCOST
FROM CHULGOT
WHERE CFMDEPT LIKE '71%'
NESTED LOOPS
TABLE ACCESS FULL ORDER1T
TABLE ACCESS BY ROWID CHULGOT
INDEX RANGE SCAN CH_CFMDEPT
rows,
71 sec
SQL> SELECT ORDNO, CHULNO, STATUS
FROM ORDER1T X, CHULGOT Y
WHERE X.CUSTNO = Y.CUSTNO
AND X.ORDDEPT = Y.CFMDEPT
AND y.CHULDATE LIKE ‘1307%'
NUMBER type
TABLE ACCESS FULL CHULGOT
rows,
30 sec
NUMBER > (CHAR or VARCHAR)
INDEX 활용기준
INDEX 적용기준
6블럭 이상의 테이블에 적용(6블럭 이하는 연결고리만)
컬럼의 분포도가 10~15% 이내인 경우 적용
분포도가 범위 이내더라도 절대량이 많은 경우에는 클러스터링 검토
분포도가 범위 이상이더라도 부분범위처리를 목적인 경우 적용
인덱스만 사용하여 해결하고자 하는 경우 분포도가 나쁘더라도 적용 가능
INDEX 활용기준
INDEX 선정기준
분포도가 좋은 컬럼은 단독적으로 생성하여 활용도 향상
자주 조합되어 사용되는 경우는 결합인덱스 생성
각종 엑세스 경우의 수를 만족하도록 인덱스 간의 역할 분담
가능한 수정이 빈번하지 않은 컬럼
기본키 및 외부키 (조인의 연결고리가 되는 컬럼)
결합 인덱스의 컬럼 순서 선정에 주의
INDEX 활용기준
INDEX 선정절차
• 해당 테이블 사용하는 모든 쿼리의 액세스 유형 조사
1. 해당 테이블의 액세스 유형조사
• 인덱스 후보로 어떤 컬럼이 좋을지 선정하고 각 컬럼에 데이터 분포도 분석
2. 대상 컬럼의 선정 및 분포도 분석
• FOR문 안에서 실행되는 쿼리 일 경우 최적에 액세스 경로를 탈 수 있게 최적화
3. 반복 수행되는 액세스 경로의 해결
• 데이터량이 많은 경우 검토(초기에는 적용하기 쉬우나 운영 중에는 초기에 비해 적용이 어려움)
4. 클러스터링 검토
• 컬럼의 순서를 결정
5. 인덱스 컬럼의 조합 및 순서의 결정
• 잘못된 쿼리로 인해 인덱스 적용이 안 될 수 있음. 이런 쿼리들을 최적화 쿼리로 수정
• 모든 작업이 완료되면 일괄 적용
6. 시험생성 및 테스트 그리고 일괄 수정
INDEX 활용기준
결합 INDEX 순서 절차
 항상 사용하는가 ?
 항상 EQUAL로 사용되는가?
 분포도가 좋은 컬럼 우선
 SORT 순서는?
 어떤 컬럼을 추가?(후보선수)
추가된 인덱스가 미치는 영향
SELECT *
FROM TAB1
WHERE A = '10'
AND B = ‘130415'
AND C = '123'
AB C
INDEX1 INDEX2
A = '10‘
B = ‘130415'
C = '123'
(INDEX1 사용)
D column 추가
ABD C
INDEX1 INDEX2
C = '123'
(INDEX2 사용)
A = '10‘
B = ‘130415‘
D LIKE ‘A%’
추가된 인덱스가 미치는 영향
예제
CHULITEM table Primary Key : CHULNO + ORDNO + ITEM
SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY
FROM CHULITEM
WHERE CHULNO = '2565'
AND ORDNO = '8584'
AND LOT = 'P0009'
1 rows,
0.01sec
TABLE ACCESS BY ROWID CHULITEM
INDEX RANGE SCAN PK_CHULITEM
SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY
FROM CHULITEM
WHERE CHULNO = '2565'
AND ORDNO = '8584'
AND LOT = 'P0009'
1 rows,
37.7sec
SQL> CREATE INDEX CI_LOT ON CHULITEM (LOT)
TABLE ACCESS BY ROWID CHULITEM
INDEX RANGE SCAN CI_LOT
SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY
FROM CHULITEM
WHERE CHULNO = '2565'
AND ORDNO = '8584'
AND LOT = 'P0009'
1 rows,
0.01 sec
SQL> CREATE INDEX CI_LOT_ITEM ON CHUITEM (LOT,ITEM)
TABLE ACCESS BY ROWID CHULITEM
INDEX RANGE SCAN PK_CHULITEM
4주차
JOIN
기본 실력 Test
조인에 대한 이해
문제
상품명을 가져 올 때 어떤 방법이 비용을 절약 할 수 있는 방법인가?
상품 테이블(100건)
상품번호 (PK)
상품명 VARCHAR2(4BYTE)
주문 테이블(10만건)
주문번호 (PK)
상품번호(FK)
①상품테이블에 상품명을 추가해서 주문테이블과 조인해서 검색
SELECT * FROM 주문, 상품
WHERE 주문.상품번호 = 상품.상품번호
주문 테이블(10만건)
주문번호 (PK)
상품명 VARCHAR2(4BYTE)
②주문테이블에 상품명을 추가해서 주문테이블만 검색
SELECT * FROM 주문
상품명 컬럼 4byte를 추가하게 되면
1Row는 4x100,000 = 400,000
상품명 컬럼 4byte를 추가하게 되면
1Row는 4x100 = 400
수행속도의 결정요소 DRIVING!
TAB2
K . . . . . . .
A . . . . . . .
. . . . . . . .
D . . . . . . .
Z . . . . . . .
KEY2 FLD . . .
FLD . . . KEY1
. . . . . . . . . A
. . . . . . . . . D
. . . . . . . . . B
. . . . . . . . . .
. . . . . . . . . K
K . . . . . . .
A . . . . . . .
. . . . . . . .
D . . . . . . .
Z . . . . . . .
KEY2 FLD . . .
. . . . . . . . . A
. . . . . . . . . D
. . . . . . . . . B
. . . . . . . . . .
. . . . . . . . . K
FLD . . . KEY1
INDEX 있음
TAB1
INDEX 있음
TAB1 TAB2
INDEX 있음 INDEX 없음
-인덱스가 한쪽만 있으면 FULL SCAN이 발생
-두쪽 다 인덱스가 없으면 SORT MERGE 방법으로 처리
ACCESS량에 따른 처리 속도
 ACCESS량이 많음
운반
단위
INDEX
(FLD1)
TAB1 TAB2INDEX
(KEY2)
FLD1='10'
KEY2
=
KEY1
o
x
5000 row
x
x
x
x
.
.
.
.
100 row 50 row
.
.
.
.
.
.
.
.
x o
o
FLD2 like
‘A%’
 ACCESS량이 적음
운반
단위
INDEX
(FLD2)
INDEX
(KEY1)
KEY1
=
KEY2
FLD2 like
'A%'
100 row
.
.
.
.
70 row50 row
.
.
.
.
.
.
.
.
.
.
.
.
x
TAB1 TAB2
o
o
FLD1
=‘10’
SELECT A.FLD1, ..., B.FLD1,...
FROM TAB2 B, TAB1 A
WHERE A.KEY1 = B.KEY2
AND B.FLD2 like 'A%'
AND A.FLD1 = '10'
15 Sec 1 Sec
ACCESS량에 따른 처리 속도
ACCESS량이 많은 방식을 ACCESS량이 적은 방식으로 실행되게 하려면
위 쿼리를 어떻게 변경 해야 할까요?
JOIN과 LOOP QUERY
JOIN LOOP-QUERY
운반
단위
SQL
SQL
SQL
TAB1 TAB2
.
.
.
.
SQL
SQL
2
차
가
공
.
.
.
.
.
.
.
.
2
차
가
공
운반
단위
TAB1 TAB2
.
.
.
.
.
.
.
.
.
.
.
.
for(i = 0; i < 100; i++){
for(j = 0; j < 100; j++){
// Do Anything..
}
}
Nested Loops 조인
Nested Loops = For 문
Nested Loops 조인
운반
단위
INDEX
(FLD1) TAB1 TAB2
INDEX
(KEY2)
FLD1=
'AB'
TABLE
ACCESS
BY
ROWID
KEY2
=
KEY1
TABLE
ACCESS
BY
ROWID
FLD2 ='10'
check
o
o
o
x
SELECT A.FLD1, ..., B.FLD1,...
FROM TAB1 A, TAB2 B
WHERE A.KEY1 = B.KEY2
AND A.FLD1 = 'AB'
AND B.FLD2 = '10'
• 모든 DBMS에서 사용
• 부분범위처리 가능
• 먼저 처리되는 테이블의
처리범위에 따라 처리량 결정
• 랜덤(Random) 액세스 위주
• 연결고리 상태에 따라 영향이 큼
• 주로 좁은 범위 처리에 유리
Nested Loops 조인
SELECT /*+ ORDERED USE_NL(E) */
E.EMPNO, E.ENAME, D.DNAME, E.JOB, E.SAL
FROM DEPT D, EMP E
WHERE E.DEPTNO = D.DEPTNO …………… ①
AND D.LOC = 'SEOUL' …………… ②
AND D.GB = '2' …………… ③
AND E.SAL >= 1500 …………… ④
ORDER BY SAL DESC
* pk_dept : dept.deptno
* dept_loc_idx : dept.loc
* pk_emp : emp.empno
* emp_deptno_idx : emp.deptno
* emp_sal_idx : emp.sal
인덱스 구조
문제! 조건 비교 순서가 어떻게 사용될까요?
Execution Plan
---------------------------------------------------
0 SELECT STATEMENT
1 0 SORT ORDER BY
2 1 NESTED LOOPS
3 2 TABLE ACCESS BY INDEX ROWID DEPT
4 3 INDEX RANGE SCAN DEPT_LOC_IDX
5 2 TABLE ACCESS BY INDEX ROWID EMP
6 5 INDEX RANGE SCAN EMP_DEPTNO_IDX
② → ③ → ① → ④
Nested Loops 조인
SELECT /*+ ORDERED USE_NL(E) */
E.EMPNO, E.ENAME, D.DNAME, E.JOB, E.SAL
FROM DEPT D, EMP E
WHERE E.DEPTNO = D.DEPTNO …………… ③
AND D.LOC = 'SEOUL' …………… ①
AND D.GB = '2' …………… ②
AND E.SAL >= 1500 …………… ④
ORDER BY SAL DESC
① ② D.LOC = ‘SEOUL’의 범위가 넓으면 전체적인 속도 저하 발생
체크조건인 D.GB = ‘2’ 범위가 넓으면 결합인덱스 고려
③ ④ E.DEPTNO, D.DEPTNO 각 컬럼이 데이터 타입이 일치하는지 확인
DRIVING 될 E.DEPT_NO에 인덱스가 있는지 확인
E.SAL 범위가 넓으면 결합인덱스 고려
NL JOIN이 효과적이지 못 할 때 HASH JOIN, SORT MERGE JOIN 고려
Nested Loops 조인
• 블록단위로 I/O를 수행
• 하나의 레코드만 읽어도 블록을 통째로 읽음
• RANDOM ACCESS는 빠르지만 비효율이 존재
대량의 데이터를 조인할 때 비효율적
• 대용량 데이터 처리 시 매우 치명적인 한계를 보임
• 대용량이더라도 부분범위 처리 상황에서 빠른 속도를 낼 수 있음
순차적 조인
• 다른 조인방식과 비교 했을 때 인덱스 구성 전략이 중요
• 소량의 데이터를 처리 할 때 효율적
• Prefetch(Table,Index), Buffer Pinning 효과로 액세스 획기적 감소 (Non unique)
• 가능한 Nested Loop방식으로 처리하고 비효율적일 때 Hash 조인과, Merge 조인 고려
온라인 환경에 적합한 조인
Nested Loop 특징
각 테이블을 조건에 맞게 정렬 한 후 Merge
Sort Merge 조인
운반단위
.
.
.
S
O
R
T
.
.
.
.
.
.
.
.
.
.
.
.
S
O
R
T
.
.
.
.
.
.
.
.
.
Sort Merge 조인
효율적인SQL
방법
옵티마이져
사용자
Nested Loop로
처리해
쓸만한 인덱스가 있나?..
없네;; 소트머지 조인이나
해쉬 조인을 써야겠다~
Sort Merge 조인
SELECT /*+USE_MERGE(A,B)*/
A.FLD1, ..., B.FLD2,...
FROM TAB1 A, TAB2 B
WHERE A.KEY1 = B.KEY2
AND A.FLD1 = 'AB'
AND B.FLD2 = '10'
INDEX
(FLD1)
TAB1 TAB2
FLD1=
'AB'
TABLE
ACCESS
BY
ROWID
운반단위
.
.
.
S
O
R
T
INDEX
(FLD2)
FLD2=
'10'
TABLE
ACCESS
BY
ROWID
a.KEY1=
b.KEY2 를
조건으로
Merge
.
.
.
.
.
.
.
.
.
.
.
.
S
O
R
T
.
.
.
.
.
.
.
.
.
• 전체범위 처리 (First, Second)
• 인덱스 유무에 영향을 받지 않음
• 주로 넓은 범위 처리에 유리
• 조인 컬럼에 인덱스가 없을 때 유리
• NL과 같은 스캔 액세스 위주
• PGA에있는 SQLAREA 사용하여
래치 획득 과정이 없음
Sort Merge 조인
Sort Merge(뭐지?) 단계
1. Sort 단계 : 양쪽 집합을 조인 컬럼 기준으로 정렬
2. Merge 단계 : 정렬된 양쪽 집합을 서로 머지
Point !!
정렬해서 merge한다는 점만 다를 뿐 수행과정은 Nested Loop와 다르지 않음
왜? Sort Area 때문에~
= SORT!
PGA <- SQL AREA
ORACLE에서 사용 하는 메모리
SGA : 모든 서버 및 백그라운드 프로세스에 의해 공유
PGA : 각 서버 프로세스에 대한 데이터 및 제어정보를 포함
공용으로 쓰는 메모리
독립적으로 사용되는 메모리
Sort Merge 조인
같이 사용 하는 공간
모든 유저에게 할당하는 각각의
프로세스가 독점으로 사용하는 공간
Sort Merge 조인
정렬공간
(Sort
Area)
세션정보
커서상태
정보
변수저장
공간
ORDER BY
GROUP BY
ROLLUP
DISTINCT
UNION
MINUS
INSERT SELECT
인덱스 생성
BITMAP 연산 수행
SORT MERGE 조인
HASH JOIN
통계정보
독립적인 메모리 공간이어서 래치 획득 과정이 없어서 빠름
Sort Merge 조인
Sort Merge Join……
언제 어떻게 써야 좋은 거야?
Sort Merge 조인
First 테이블에 소트 연산을 대체할 인덱스가 있을 때
CREATE INDEX dept_idx ON dept(loc, deptno);
CREATE INDEX emp_idx ON emp(job, deptno);
인덱스 생성
SELECT /*+ ordered use_merge(e) */ *
FROM dept d, emp e
WHERE d.deptno = e.deptno
AND d.loc = 'CHICAGO’
AND e.job = 'SALESMAN’
ORDER BY e.deptno;
쿼리 실행
실행 계획
SORT 오퍼레이션 줄이기!!
FIRST 테이블 부분범위 처리 유도하
Sort Merge 조인
조인할 First 집합이 이미 정렬돼 있을 때
GROUP BY, ORDER BY, DISTINCT를 이용해서 이미 정렬 된 경우 효율적!
SELECT /*+ ORDERED USE_MERGE(D) */
D.DEPTNO, D.DNAME, E.AVG_SAL
FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROM EMP GROUP BY DEPTNO) E
, DEPT D
WHERE E.DEPTNO = D.DEPTNO
10g R2에서 도입된 hash group by로 효율이 낮아 지기 때문에
Sort group by로 유도 해야 함!
쿼리 실행
쿼리 실행
Sort Merge 조인
조인할 First 집합이 이미 정렬돼 있을 때
GROUP BY, ORDER BY, DISTINCT를 이용해서 이미 정렬 된 경우 효율적!
SELECT /*+ ORDERED USE_MERGE(D) */
D.DEPTNO, D.DNAME, E.AVG_SAL
FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROMEMP GROUP BY DEPTNO ORDER BY DEPTNO) E
, DEPT D
WHERE E.DEPTNO = D.DEPTNO
9i 에서는 Sort group by로 처리 됨(hash group by가 없음)
쿼리 실행
쿼리 실행
Sort Merge 조인
조인 조건식이 등치(=) 조건이 아닐 때
Hash 조인은 = 조건만 사용 가능 하지만
merge조인은 between, <, <=, >, >= 조건도 사용가능!
SELECT /*+ ORDERED USE_MERGE(E) */
D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME
FROM DEPT D, EMP E
WHERE D.DEPTNO <= E.DEPTNO
WHERE D.DEPTNO >= E.DEPTNO
ASC
DESC
NESTED LOOP, SORT MEGE JOIN 예제
MERGE JOIN
SORT JOIN
TABLE ACCESS FULL CHULGOT
SORT JOIN
TABLE ACCESS FULL CUSTOMER
SQL> SELECT X.CUSTNO,CHULDATE, CUSTNAME
FROM CHULGOT X, CUSTOMER Y
WHERE X.CUSTNO = Y.CUSTNO
5.44 sec
NESTED LOOPS
TABLE ACCESS FULL CHULGOT
TABLE ACCESS BY ROWID CUSTOMER
INDEX UNIQUE SCAN PK_CUSTNO
0.02 sec
SORT GROUP BY
MERGE JOIN
SORT JOIN
TABLE ACCESS FULL CHULGOT
SORT JOIN
TABLE ACCESS FULL CUSTOMER
SQL> SELECT NATION, SUM(CHULTIME)
FROM CHULGOT X, CUSTOMER Y
WHERE X.CUSTNO = Y.CUSTNO
GROUP BY NATION
8.33 sec
SQL> SELECT /*+ RULE */
NATION, SUM(CHULTIME)
FROM CHULGOT X, CUSTOMER Y
WHERE X.CUSTNO = Y.CUSTNO
GROUP BY NATION
SORT GROUP BY
NESTED LOOPS
TABLE ACCESS FULL CUSTOMER
TABLE ACCESS BY ROWID CHULGOT
INDEX RANGE SCAN CH_CUSTNO
17.5 sec
JOIN 방법의 결정
Nested
Loop
JOIN
좁 다
넓 다
Driving
table
결정
부
분
범
위
처
리
Check
조건
Sort
Merge
JOIN
넓 다
좁 다
가 능
불가능
유 리
불 리
Driving 과
Check 조건
교환
가 능 Driving
조건
First_rows
불가능
상수를 추가로 넣는게
유리한지 비교
All_rows
Hash 조인
Nested loop, Sort merge join의 대안
HASH JOIN
7.3
HASH JOIN 원리
2개 테이블 중 작은 집합을
HashMap으로 생성
큰 집합을 읽어서
해시테이블을 탐색하며 조인
-Nested Loop Join처럼 Random액세스 부하가 없음.
-Sort Merge Join처럼 미리 양쪽 집합을 정렬하는 부담이 없음.
-Hash 테이블 생성 시 많은 COST가 발생됨.
-Hash Area에 담길 정도의 크기로 만들어져야 성능이 향상 됨.
Hash Join Build Input
옵티마이저의 실수
HASH JOIN 원리
SELECT /*+USE_HASH(D E) */
D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME
FROM SCOTT.DEPT D, SCOTT.EMP E
WHERE D.DEPTNO = E.DEPTNO;
SELECT /*+LEADING(E) USE_HASH(D E) */
D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME
FROM SCOTT.DEPT D, SCOTT.EMP E
WHERE D.DEPTNO = E.DEPTNO;
HASH JOIN 원리
효율적인
SQL작성방
법
HASH AREA가 초과 될 때
옵티마이저의 생각 읽기
Grace 해시 조인 > Hybrid 해시 조인 / Recursive 해시 조인 (Nested Loop 해시 조인)
HASH JOIN 원리
Build input 키 값 중복이 많이 발생할 때 튜닝 방법
SELECT /*+USE_HASH(O F) */
COUNT(*)
FROM ORDER O,
CONTRACT F
WHERE O.PRODUCT_CD = F.PRODUCT_CD
AND O.ORDER_DT = F.CONTRACT_DT
AND O.ORDER_NO IN (F.ORDER_NO_BUY, F.ORDER_NO_SELL);
AND F.CONTRACT_DT = :주문일자
SELECT /*+ GATHER_PLAN_STATISTICS USE_HASH(O F) */
COUNT(*)
FROM ORDER O,
(SELECT PRODUCT_CD, FILL_DT, ORDER_NO_BUY AS ORDER_NO FROM CONTRACT
UNION ALL
SELECT PRODUCT_CD, FILL_DT, ORDER_NO_SELL AS ORDER_NO FROM CONTRACT) F
WHERE O.PRODUCT_CD = F.PRODUCT_CD
AND O.ORDER_DT = F.CONTRACT_DT
AND O.ORDER_NO = F.ORDER_NO
AND F.CONTRACT_DT = :주문일자
71초
0.16초
HASH JOIN 원리
HASH JOIN 사용 기준
한 쪽 테이블이 Hash Area에 담겨야 함.
Build Input 해시 키 컬럼에 중복 값이 거의 없어야 함.
조인 컬럼에 적당한 인덱스가 없어 NL조인이 비효율적일 때
조인 액세스량이 많아 Random 액세스 부하가 심할 때
소트머지조인을 하기에는 두 테이블이 너무 클 때
수행빈도가 낮고 쿼리 수행 시간이 오래 걸리는 대용량테이블 조인 할 때
Outer Join
Outer...
Join...
Outer NL Join, Outer Sort Merge Join
Outer join의 함정
문제
Optimizer는 고객 테이블, 주문 테이블 중 어느 테이블을 먼저 Driving 할 것인가?
고객 테이블(100건)
고객번호 (PK)
주문테이블(1,000만건)
주문번호(PK)
고객번호(FK)
SELECT *
FROM 고객, 주문
WHERE 고객.고객번호(+) = 주문.고객번호
고객테이블이 먼저 Driving 되어야 하지만
Outer 조건 때문에 주문 테이블을
먼저 Driving 하게 됨.
(키 존재 여부를 Outer가 아닌쪽을 전체 조
회 해봐야 알 수 있기 때문에)
(+)기호가 붙지 않은 테이블이 먼저 드라이빙!!
Outer Join 제거 예제
튜닝 전 튜닝 후
Outer Join
효율적인
SQL작성방
법
RIGHT OUTER HASH JOIN…!!!! (10g)
Outer Hash Join
매칭된 레코드는 결과집합에 삽입
매칭되지 않은 레코드는 마지막에 붙임
Left Outer 조인 + Union All + Anti 조인(Not Exists)
Full Outer Join
SELECT A.고객ID, A.입금액, B.출금액
FROM (SELECT 고객ID, SUM(입금액) 입금액 FROM 입금 GROUP BY 고객ID)A
,(SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID)B
WHERE B.고객ID(+)=A.고객ID
UNION ALL
SELECT 고객ID, NULL, 출금액
FROM (SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID) A
WHERE NOT EXISTS (SELECT 'X' FROM 입금 WHERE 고객ID=A.고객ID);
SELECT NVL(A.고객ID, B.고객ID) 고객ID, A.입금액, B.출금액
FROM
(SELECT 고객ID, SUM(입금액) 입금액 FROM 입금 GROUP BY 고객ID) A
FULL OUTER JOIN
(SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID) B
ON A.고객ID=B.고객ID;
일반 SELECT문과 전혀 다른 CONNECT BY!!
순환관계(CONNECT BY)
ID . . . . P_ID
A . . .
B . . . A
C . . . A
D . . . B
E . . . B
G . . . D
F . . . C
H . . . F
J . . . F
순 환 전 개 법
A
B C
D E F
H JG
구조(순환관계)가 변경 되도 식별자는 변하지 않음
잘 못 사용 시 수행속도 저하
1000
1100 1200
1110 1120 1210
1211 12121111
ID . . . .
1000 . . .
1100 . . .
1110 . . .
1111 . . .
1120 . . .
1200 . . .
1210 . . .
1211 . . .
1212 . . .
사용하기가 쉽고 간편하며 수행속도에 상대적으로 유리함
구조 변경에 매우 취약함 (식별자 변경)
구조 변경 시 과거 데이터의 수정이 필요함
C O D E 대 비 법
순환관계(CONNECT BY)
CONNECT BY SQL GENERAL SQL
SELECTSELECT LEVELLEVEL , COL1, COL2,......, COL1, COL2,......
SEUDO 컬럼
SELECT COL1, COL2,......
JOIN 테이블
FROM TAB1 (동일테이블로 조인 간주) FROM TAB1 x, TAB2 yFROM TAB1 x, TAB2 y
WHERE conditions . . . . . .WHERE conditions . . . . . .
AND check_conditions . . . . . .
CHECK 조건
JOIN 조건
CONNECT BYCONNECT BY PRIORPRIOR ID = P_IDID = P_ID
and conditions . . .and conditions . . .
WHEREWHERE x. KEY = y.KEYKEY = y.KEY
선처리 테이블
조건
START WITH conditions
AND driving_table_conditions
선처리테이블 ALIAS
순환관계(CONNECT BY) 활용
SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . .
FROM BOM
CONNECT BY PRIOR ID = P_ID
AND ID <> ‘F’
START WITH P_ID = ‘A’
특 정 경 우 만 미 추 출예 하 그 룹 미 전 개
SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . .
FROM BOM
WHERE ID <> ‘F’
CONNECT BY PRIOR ID = P_ID
START WITH P_ID = ‘A’
A
C
F
H J
B
D E
G
A
C
F
H J
B
D E
G
순환관계(CONNECT BY)
ID . . . . P_ID
A . . .
B . . . A
C . . . A
D . . . B
E . . . B
G . . . D
F . . . C
H . . . F
J . . . F
순 환 전 개 법
A
B C
D E F
H JG
최상위 P_ID는 널로 만들지 않는다.
최상위에 무의미한 ROW를 추가해서
효율을 높인다.
ROOT | NULL | NULL
순환관계(CONNECT BY) 활용
SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . .
FROM BOM
CONNECT BY PRIOR ID = P_ID
AND T_ID = 1
START WITH P_ID = ‘1000’
AND T_ID = 1
전 체 집 합 순 환 관 계소 그 룹 별 순 환 관 계
1000
1100 1200
1110 1120 1210
1211 12121111
T_ID = 1
1000
1100 1200
1110 1120 1210
1211 12121111
T_ID = 2
1000
1100 1200
1110 1120 1210
1211 12121111
T_ID = 3
A
E F
H JG
1
B2
DF
K
G
C P
H
O
SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . .
FROM BOM
CONNECT BY PRIOR ID1 = P_ID1
AND PRIOR ID2 = P_ID2
START WITH P_ID1 = ‘A’
AND P_ID2 = ‘10’
시내 주행 1등급 연비 스칼라 서브쿼리!
스칼라 서브쿼리
SELECT
(SELECT B.NAME
FROM DEPT B
WHERE B.DEPT_NO = A.EMP_NO)
FROM EMP_NO A
출력 값 : B.NAME
입력 값 : A.EMP_NO
Cache
스칼라 서브쿼리
SELECT
GET_USER_AMT(A.EMP_ID)
FROM EMP_NO A,
………
SELECT
(SELECT GET_USER_AMT(A.EMP_ID) FROM DUAL)
FROM EMP_NO A,
……… 함수 입력 값의 종류가 적을 수록 효율적
캐시 사이즈가 부족하여 해시 충돌이 발생하면
엄청난 부하를 발생 시킴!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
스칼라 서브쿼리(해시 충돌 제어 방법)
SELECT
(SELECT GET_USER_AMT(A.EMP_ID) FROM DUAL)
FROM EMP_NO A,
……… 해시 충돌이 발생하면 기존 엔티리를 밀어내고
새로운 엔트리 생성이 반복되면서 성능부하 발생!
캐시 사이즈 증가로 해시 충돌 방지!
ALTER SESSION SET “_query_execution_cache_max_size” = 3000000;
45초
0.79초
ERD
EXPLAIN PLAN
ID OPERATION OPTIONS OBJECT_NAME
1 FILTER
2 NESTED LOOPS
3 TABLE ACCESS FULL EMP
4 TABLE ACCESS BY ROWID DEPT
5 INDEX UNIQUE SCAN PK_DEPT
6 TABLE ACCESS FULL SALGRADE
1
2 6
FILTER
NESTED
LOOPS
TABLE ACCESS
(FULL) salgrade
3 4
TABLE ACCESS
(FULL) emp
TABLE ACCESS
(BY ROWID) dept
5
INDEX
(UNIQUE SCAN)
pk_dept
SELECT ename, job, sal, dname
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND not exists
(SELECT 1
FROM salgrade
WHERE emp.sal BETWEEN losal AND hisal)
마무리
테스트 어렵지 않다.
튜닝
개발
VS
무엇이 더
어려울까요?
효율적인Sql작성방법 4주차

More Related Content

What's hot

#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)
#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)
#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)탑크리에듀(구로디지털단지역3번출구 2분거리)
 
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지탑크리에듀(구로디지털단지역3번출구 2분거리)
 
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지탑크리에듀(구로디지털단지역3번출구 2분거리)
 
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지탑크리에듀(구로디지털단지역3번출구 2분거리)
 
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지탑크리에듀(구로디지털단지역3번출구 2분거리)
 
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQLPgDay.Seoul
 
MySQL 인덱스의 기초
MySQL 인덱스의 기초MySQL 인덱스의 기초
MySQL 인덱스의 기초Hoyoung Jung
 
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Circulus
 
WINDOW FUNCTION의 이해와 활용방법_Wh oracle
WINDOW FUNCTION의 이해와 활용방법_Wh oracleWINDOW FUNCTION의 이해와 활용방법_Wh oracle
WINDOW FUNCTION의 이해와 활용방법_Wh oracle엑셈
 
2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자Circulus
 
Oracle Query Optimizer 관련 Parameter_OracleParameter
Oracle Query Optimizer 관련 Parameter_OracleParameterOracle Query Optimizer 관련 Parameter_OracleParameter
Oracle Query Optimizer 관련 Parameter_OracleParameter엑셈
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL TuningPgDay.Seoul
 

What's hot (20)

#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)
#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)
#12.SQL초보에서 schema Objects까지(구로IT학원/IT실무교육학원/국비지원IT교육학원/오라클교육/자바교육/닷넷교육학원추천)
 
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지
[오라클교육/SQL교육/IT교육/실무중심교육학원추천_탑크리에듀]#4.SQL초보에서 Schema Objectes까지
 
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지
[구로IT학원추천/구로디지털단지IT학원/국비지원IT학원/재직자/구직자환급교육]#9.SQL초보에서 Schema Objects까지
 
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지
오라클강의/자바강의/닷넷강의/자마린교육/아두이노교육학원추천_#13.SQL초보에서 Schema Objects까지
 
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지
(재직자환급교육/사업주위탁/IT실무교육/구로IT학원/오라클교육/SQL기초강좌/IT강좌)#10.SQL초보에서 Schema Objects까지
 
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
 
IT실무교육학원/자바학원/오라클학원/SQL기초학원추천_#11.SQL초보에서 Schema Objects까지
IT실무교육학원/자바학원/오라클학원/SQL기초학원추천_#11.SQL초보에서 Schema Objects까지IT실무교육학원/자바학원/오라클학원/SQL기초학원추천_#11.SQL초보에서 Schema Objects까지
IT실무교육학원/자바학원/오라클학원/SQL기초학원추천_#11.SQL초보에서 Schema Objects까지
 
MySQL 인덱스의 기초
MySQL 인덱스의 기초MySQL 인덱스의 기초
MySQL 인덱스의 기초
 
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
#1.SQL초보에서 Schema Objects까지(SQL학원/오라클학원/IT실무교육학원/재직자/실업자교육학원추천)
 
(오라클힌트/SQL튜닝 강좌)쿼리튜닝을 위한 오라클의 10053 이벤트
(오라클힌트/SQL튜닝 강좌)쿼리튜닝을 위한 오라클의 10053 이벤트(오라클힌트/SQL튜닝 강좌)쿼리튜닝을 위한 오라클의 10053 이벤트
(오라클힌트/SQL튜닝 강좌)쿼리튜닝을 위한 오라클의 10053 이벤트
 
(오라클힌트,SQL튜닝강좌#25)오라클WITH구문,서브쿼리 팩토링
(오라클힌트,SQL튜닝강좌#25)오라클WITH구문,서브쿼리 팩토링(오라클힌트,SQL튜닝강좌#25)오라클WITH구문,서브쿼리 팩토링
(오라클힌트,SQL튜닝강좌#25)오라클WITH구문,서브쿼리 팩토링
 
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리
 
WINDOW FUNCTION의 이해와 활용방법_Wh oracle
WINDOW FUNCTION의 이해와 활용방법_Wh oracleWINDOW FUNCTION의 이해와 활용방법_Wh oracle
WINDOW FUNCTION의 이해와 활용방법_Wh oracle
 
2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자
 
복수행 서브쿼리
복수행 서브쿼리복수행 서브쿼리
복수행 서브쿼리
 
Oracle Query Optimizer 관련 Parameter_OracleParameter
Oracle Query Optimizer 관련 Parameter_OracleParameterOracle Query Optimizer 관련 Parameter_OracleParameter
Oracle Query Optimizer 관련 Parameter_OracleParameter
 
단일행 서브쿼리
단일행 서브쿼리단일행 서브쿼리
단일행 서브쿼리
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning
 
일반함수 및 조건식 1
일반함수 및 조건식 1일반함수 및 조건식 1
일반함수 및 조건식 1
 
3. linked list
3. linked list3. linked list
3. linked list
 

Viewers also liked

SQL쿼리튜닝팁 - 허성
SQL쿼리튜닝팁 - 허성SQL쿼리튜닝팁 - 허성
SQL쿼리튜닝팁 - 허성ETRIBE_STG
 
성능 좋은 SQL 작성법
성능 좋은 SQL 작성법성능 좋은 SQL 작성법
성능 좋은 SQL 작성법Devgear
 
데이터베이스 시스템 chapter4_STG박하은
데이터베이스 시스템 chapter4_STG박하은데이터베이스 시스템 chapter4_STG박하은
데이터베이스 시스템 chapter4_STG박하은ETRIBE_STG
 
지적재산권
지적재산권지적재산권
지적재산권ETRIBE_STG
 
Spring Security
Spring SecuritySpring Security
Spring SecurityETRIBE_STG
 
데이터베이스 시스템 chapter2_STG박하은
데이터베이스 시스템 chapter2_STG박하은데이터베이스 시스템 chapter2_STG박하은
데이터베이스 시스템 chapter2_STG박하은ETRIBE_STG
 
데이터베이스 시스템 chapter1_STG박하은
데이터베이스 시스템 chapter1_STG박하은데이터베이스 시스템 chapter1_STG박하은
데이터베이스 시스템 chapter1_STG박하은ETRIBE_STG
 
(130105) #fitalk trends in d forensics (dec, 2012)
(130105) #fitalk   trends in d forensics (dec, 2012)(130105) #fitalk   trends in d forensics (dec, 2012)
(130105) #fitalk trends in d forensics (dec, 2012)INSIGHT FORENSIC
 
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응INSIGHT FORENSIC
 
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석Kyunghoon Kim
 
System hacking basics
System hacking basicsSystem hacking basics
System hacking basicsgnomekr
 
Pdf 이교수의 멘붕하둡_pig
Pdf 이교수의 멘붕하둡_pigPdf 이교수의 멘붕하둡_pig
Pdf 이교수의 멘붕하둡_pigMichelle Hong
 
모바일 게임 보안
모바일 게임 보안모바일 게임 보안
모바일 게임 보안TOAST_NHNent
 
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안NAIM Networks, Inc.
 
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013가장 심각한 웹 애플리케이션 보안 위험 10가지-2013
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013봉조 김
 
개발자가 도전하는 MariaDB 서버구축
개발자가 도전하는 MariaDB 서버구축개발자가 도전하는 MariaDB 서버구축
개발자가 도전하는 MariaDB 서버구축정해 이
 

Viewers also liked (20)

SQL쿼리튜닝팁 - 허성
SQL쿼리튜닝팁 - 허성SQL쿼리튜닝팁 - 허성
SQL쿼리튜닝팁 - 허성
 
성능 좋은 SQL 작성법
성능 좋은 SQL 작성법성능 좋은 SQL 작성법
성능 좋은 SQL 작성법
 
데이터베이스 시스템 chapter4_STG박하은
데이터베이스 시스템 chapter4_STG박하은데이터베이스 시스템 chapter4_STG박하은
데이터베이스 시스템 chapter4_STG박하은
 
지적재산권
지적재산권지적재산권
지적재산권
 
Spring Security
Spring SecuritySpring Security
Spring Security
 
데이터베이스 시스템 chapter2_STG박하은
데이터베이스 시스템 chapter2_STG박하은데이터베이스 시스템 chapter2_STG박하은
데이터베이스 시스템 chapter2_STG박하은
 
데이터베이스 시스템 chapter1_STG박하은
데이터베이스 시스템 chapter1_STG박하은데이터베이스 시스템 chapter1_STG박하은
데이터베이스 시스템 chapter1_STG박하은
 
(130105) #fitalk trends in d forensics (dec, 2012)
(130105) #fitalk   trends in d forensics (dec, 2012)(130105) #fitalk   trends in d forensics (dec, 2012)
(130105) #fitalk trends in d forensics (dec, 2012)
 
Korean Word Network
Korean Word NetworkKorean Word Network
Korean Word Network
 
Db활용가이드
Db활용가이드Db활용가이드
Db활용가이드
 
Sdn and Security
Sdn and SecuritySdn and Security
Sdn and Security
 
Welcome to python
Welcome to pythonWelcome to python
Welcome to python
 
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응
(Fios#03) 2. 네트워크 가상화 환경에서의 침해대응
 
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석
[20140830, Pycon2014] NetworkX를 이용한 네트워크 분석
 
System hacking basics
System hacking basicsSystem hacking basics
System hacking basics
 
Pdf 이교수의 멘붕하둡_pig
Pdf 이교수의 멘붕하둡_pigPdf 이교수의 멘붕하둡_pig
Pdf 이교수의 멘붕하둡_pig
 
모바일 게임 보안
모바일 게임 보안모바일 게임 보안
모바일 게임 보안
 
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안
[White Paper] SDN 기반 공격 탐지차단 강화를 위한 네트워크 관리 정보 구성 방안
 
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013가장 심각한 웹 애플리케이션 보안 위험 10가지-2013
가장 심각한 웹 애플리케이션 보안 위험 10가지-2013
 
개발자가 도전하는 MariaDB 서버구축
개발자가 도전하는 MariaDB 서버구축개발자가 도전하는 MariaDB 서버구축
개발자가 도전하는 MariaDB 서버구축
 

Similar to 효율적인Sql작성방법 4주차

Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124한 경만
 
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3Seok-joon Yun
 
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천탑크리에듀(구로디지털단지역3번출구 2분거리)
 
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracleTABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle엑셈
 
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracleSQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle엑셈
 
Python + Excel
Python + Excel Python + Excel
Python + Excel POSTECH
 
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기Kenu, GwangNam Heo
 
Alphago at a Glance
Alphago at a GlanceAlphago at a Glance
Alphago at a GlanceDataya Nolja
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산S.O.P.T - Shout Our Passion Together
 
[212]검색엔진dot의내부 강희구최규식
[212]검색엔진dot의내부 강희구최규식[212]검색엔진dot의내부 강희구최규식
[212]검색엔진dot의내부 강희구최규식NAVER D2
 
하이브 최적화 방안
하이브 최적화 방안하이브 최적화 방안
하이브 최적화 방안Teddy Choi
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQLI Goo Lee
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작Terry Cho
 
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2Seok-joon Yun
 

Similar to 효율적인Sql작성방법 4주차 (20)

6.4 hints for access paths(index)
6.4 hints for access paths(index)6.4 hints for access paths(index)
6.4 hints for access paths(index)
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124
 
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
 
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천
#25.SQL초보에서 Schema Objects까지_구로IT학원/국비지원IT학원추천/구로디지털단지IT학원/재직자환급교육추천
 
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracleTABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
 
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracleSQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
 
Python + Excel
Python + Excel Python + Excel
Python + Excel
 
문자함수(1)
문자함수(1)문자함수(1)
문자함수(1)
 
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
 
Alphago at a Glance
Alphago at a GlanceAlphago at a Glance
Alphago at a Glance
 
4. stack
4. stack4. stack
4. stack
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산
[SOPT] 데이터 구조 및 알고리즘 스터디 - #02 : 스택, 큐, 수식 연산
 
3.6 실행계획 SQL 연산 (NESTED LOOP SEMI-JOIN)
3.6 실행계획 SQL 연산 (NESTED LOOP SEMI-JOIN)3.6 실행계획 SQL 연산 (NESTED LOOP SEMI-JOIN)
3.6 실행계획 SQL 연산 (NESTED LOOP SEMI-JOIN)
 
[212]검색엔진dot의내부 강희구최규식
[212]검색엔진dot의내부 강희구최규식[212]검색엔진dot의내부 강희구최규식
[212]검색엔진dot의내부 강희구최규식
 
1.7 튜닝의도구 sql autorace
1.7 튜닝의도구 sql autorace1.7 튜닝의도구 sql autorace
1.7 튜닝의도구 sql autorace
 
하이브 최적화 방안
하이브 최적화 방안하이브 최적화 방안
하이브 최적화 방안
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQL
 
Ch10
Ch10Ch10
Ch10
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작
 
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
 

Recently uploaded

(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?Jay Park
 
데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법JMP Korea
 
JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!JMP Korea
 
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement MethodologyJMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement MethodologyJMP Korea
 
공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화JMP Korea
 
JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례JMP Korea
 
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석JMP Korea
 
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개JMP Korea
 

Recently uploaded (8)

(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
 
데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법
 
JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!
 
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement MethodologyJMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
 
공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화
 
JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례
 
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
 
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
 

효율적인Sql작성방법 4주차

  • 1. 본서의 모든 이미지 출처는 생략합니다. IT역량강화 과정 효율적인SQL작성방법 4주차 시스템개발3팀 강희동
  • 3. 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
  • 4. 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
  • 5. 전체범위 VS 부분범위 전 체 범 위 처 리 2 차 가 공 운반단위 • • • • 1 차 스 캔 Full Range Scan 후 가공하여 Array Size 만큼 추출 부 분 범 위 처 리 2 차 가 공 운반단위 1 차 스 캔 조건을 만족하는 Row 수가 Array Size 에 도달되면 멈춤
  • 7. RANDOM ACCESS 운반 단위 INDEX (FLD) ..... 2 차 가 공 TAB TAB 운반 단위 o x o o o x o x ..... x x 2 차 가 공 o o Index Range Scan Full Table Scan RANDOM ACCESS가 많이 발생되면 I/O효율이 떨어집니다.
  • 8. INDEX의 중요성! 테이블 드라이빙 우선순위 부서 테이블(100건) 부서번호 (PK) 사원 테이블(10만건) 사원번호 (PK) 부서번호(FK) ① ② 조건 -부서테이블, 사원테이블에는 PK 인덱스만 존재 -전체 데이터 검색 문제 1번 테이블이 먼저 드라이빙 하는게 유리할까요? 2번 테이블이 먼저 드라이빙 하는게 유리할까요? -1번 테이블이 먼저 드라이빙 될 경우 부서 테이블을 100건을 스캔하고서 사원 테이블을 10만번 스캔 100 X 100,000 = 1,000,000 (백만번 스캔!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) -2번 테이블이 먼저 드라이빙 될 경우 사원테이블을 10만번 스캔하고서 부서 테이블을 스캔하는데 부서번호키가 Unique index 이기 때문에 1번만 읽고 스캔 100,000 X 1 = 100,000 (십만번 스캔)
  • 9. INDEX 손익분기점 가정 전체 10,000 row 1 block당 평균 10 row 전체 1,000 block 운반 단위 INDEX (FLD) ..... 2 차 가 공 TAB TAB 운반 단위 o x o o o x o x ..... x x 2 차 가 공 o o Index Range Scan Full Table Scan  1,000 row read를 위해 1,000 block access  낮은 Hit Ratio  10,000 row read를 위해 1,000 block access  높은 Hit Ratio 인덱스 사용여부 고려사항 Scan 범위 Hit Ratio Clustering Factor 손익 분기점 (10 ~15%)
  • 10. INDEX SCAN, FULL SCAN SWITCH NULL 이럴 때만 사용 합시다! -미 확정 값을 표현하고자 할 때 -결합인덱스의 구성 컬럼이 된다면 NOT NULL! -인덱스 조건 값으로 자주 사용 된다면 NOT NULL! 특정 값이 지나치게 많고 나머지 값만 주로 인덱스로 액세스 A사 B사 C사 D사 E사 F사 B 컬럼 값 C D E F NULL TABLE FULL SCAN INDEX RANGE SCAN
  • 11. INDEX SCAN, FULL SCAN SWITCH (78%) 4% 6% 7% 5% A BC D E COL1 분포도 KEY COL1 . . . . TABLE1 (10000 row) CREATE INDEX index_name ON table_name (COL1); COL1 = 'A' 를 그대로 COL1KEY . . . . A. . . . . . . . A. . . . . . . . A. . . . . . . . B. . . . . . . . B. . . . . . . . . . . .. . . . . . . . COL1 ROWID A . . . . A . . . . A . . . . B . . . . B . . . . . . . . . . . . TABLE1 (10000 row) INDEX1 (10000 row) COL1 = 'A' 를 COL1 NULL로 COL1KEY . . . . Null. . . . . . . . Null. . . . . . . . Null. . . . . . . . B. . . . . . . . B. . . . . . . . . . . .. . . . . . . . COL1 ROWID B . . . . . . . . . . . . C . . . . . . . . . . . . TABLE1 (10000 row) INDEX1 (2000 row) 
  • 12. INDEX 컬럼의 변형 SELECT * FROM EMP WHERE SUBSTR(DNAME,1,3) = 'ABC' SELECT * FROM EMP WHERE DNAME LIKE 'ABC%' SELECT * FROM EMP WHERE SAL * 12 = 12000000 SELECT * FROM EMP WHERE TO_CHAR(HIREDATE,'YYMMDD') = ‘130712' SELECT * FROM EMP WHERE HIREDATE = TO_DATE(‘130712','YYMMDD') SELECT * FROM EMP WHERE SAL = 12000000 / 12 SELECT * FROM EMP WHERE DEPTNO || JOB = '10SALESMAN' SELECT * FROM EMP WHERE DEPTNO = '10' AND JOB = 'SALSMAN'
  • 13. INDEX 컬럼의 변형 SELECT * FROM EMP WHERE NVL(COMM,0) < 100 ? SELECT * FROM EMP WHERE COMM < 100 SELECT * FROM EMP WHERE EMPNO BETWEEN 100 AND 200 AND NVL(JOB,'X') = 'CLERK' SELECT * FROM EMP WHERE EMPNO BETWEEN 100 AND 200 AND JOB = 'CLERK' 컬럼 값에 NULL이 존재하는 경우 해결방안 : NULL 값 0으로 변경
  • 14. INDEX 컬럼의 변형 SELECT * FROM EMP WHERE JOB = 'MANAGER' SELECT * FROM EMP WHERE RTRIM(JOB) = 'MANAGER' SELECT * FROM EMP WHERE EMPNO = 8978 SELECT * FROM EMP WHERE RTRIM(EMPNO) = 8978 SELECT CUSTNO, CHULDATE FROM CHULGOT WHERE CUSTNO LIKE 'DN%' AND RTRIM(STATUS) LIKE '9%' SELECT CUSTNO, CHULDATE FROM CHULGOT WHERE CUSTNO LIKE 'DN%' AND STATUS LIKE '9%' 의도적인 SUPPRESSING
  • 15. INDEX 컬럼의 변형 의도적인 SUPPRESSING SELECT X.CUSTNO, CHULDATE, CUSTNAME FROM MECHUL1T X, MECHUL2T Y WHERE X.SALENO = Y.SALENO AND X.SALEDEPT = '710' AND Y.SALEDATE LIKE ‘1301%' 10 Sec SELECT X.CUSTNO, CHULDATE, CUSTNAME FROM MECHUL1T X, MECHUL2T Y WHERE X.SALENO = Y.SALENO AND RTRIM(X.SALEDEPT) = '710' AND Y.SALEDATE LIKE ‘1301%' 1 Sec SELECT X.ORDNO, ORDDATE, ITEM FROM ORDER1T X, ORDER2T Y WHERE X.ORDNO = Y.ORDNO AND X.ORDDATE LIKE ‘1301%' AND Y.ORDDEPT = '710' ORDER BY ORDDATE 13 Sec SELECT X.ORDNO, ORDDATE, ITEM FROM ORDER1T X, ORDER2T Y WHERE RTRIM(X.ORDNO) = Y.ORDNO AND X.ORDDATE LIKE ‘1301%' AND Y.ORDDEPT = '710’ 1 Sec 연결고리 확인! 인덱스가 없으면 없는 쪽부터 드라이빙!!(중요!)
  • 16. INDEX 컬럼의 변형 SELECT * FROM SAMPLET WHERE NUM LIKE '9410%' CREATE TABLE SAMPLET ( CHR VARCHAR2(10), NUM NUMBER (12,3), VAR VARCHAR2(20), DAT DATE) SELECT * FROM SAMPLET WHERE CHA = 10 SELECT * FROM SAMPLET WHERE TO_NUMBER(CHA) = 10 SELECT * FROM SAMPLET WHERE TO_CHAR(NUM) LIKE '9410%' SELECT * FROM SAMPLET WHERE DAT = '01-JAN-94' SELECT * FROM SAMPLET WHERE DAT = TO_DATE('01-JAN-94') DATA TYPE의 변형
  • 17. INDEX 컬럼의 변형 DATA TYPE의 변형 TABLE ACCESS FULL CHULGOT 1 row, 28.5 sec SQL> SELECT SUM(UNCOST) FROM CHULGOT WHERE STATUS = 90 SORT AGGREGATE TABLE ACCESS BY ROWID CHULGOT INDEX RANGE SCAN CH_STATUS 1 row, 0.15 sec SQL> SELECT SUM(UNCOST) FROM CHULGOT WHERE STATUS = '90' SQL> SELECT CHULNO, CUSTNO, UNCOST FROM CHULGOT WHERE CFMDEPT LIKE '71%' NESTED LOOPS TABLE ACCESS FULL ORDER1T TABLE ACCESS BY ROWID CHULGOT INDEX RANGE SCAN CH_CFMDEPT rows, 71 sec SQL> SELECT ORDNO, CHULNO, STATUS FROM ORDER1T X, CHULGOT Y WHERE X.CUSTNO = Y.CUSTNO AND X.ORDDEPT = Y.CFMDEPT AND y.CHULDATE LIKE ‘1307%' NUMBER type TABLE ACCESS FULL CHULGOT rows, 30 sec NUMBER > (CHAR or VARCHAR)
  • 18. INDEX 활용기준 INDEX 적용기준 6블럭 이상의 테이블에 적용(6블럭 이하는 연결고리만) 컬럼의 분포도가 10~15% 이내인 경우 적용 분포도가 범위 이내더라도 절대량이 많은 경우에는 클러스터링 검토 분포도가 범위 이상이더라도 부분범위처리를 목적인 경우 적용 인덱스만 사용하여 해결하고자 하는 경우 분포도가 나쁘더라도 적용 가능
  • 19. INDEX 활용기준 INDEX 선정기준 분포도가 좋은 컬럼은 단독적으로 생성하여 활용도 향상 자주 조합되어 사용되는 경우는 결합인덱스 생성 각종 엑세스 경우의 수를 만족하도록 인덱스 간의 역할 분담 가능한 수정이 빈번하지 않은 컬럼 기본키 및 외부키 (조인의 연결고리가 되는 컬럼) 결합 인덱스의 컬럼 순서 선정에 주의
  • 20. INDEX 활용기준 INDEX 선정절차 • 해당 테이블 사용하는 모든 쿼리의 액세스 유형 조사 1. 해당 테이블의 액세스 유형조사 • 인덱스 후보로 어떤 컬럼이 좋을지 선정하고 각 컬럼에 데이터 분포도 분석 2. 대상 컬럼의 선정 및 분포도 분석 • FOR문 안에서 실행되는 쿼리 일 경우 최적에 액세스 경로를 탈 수 있게 최적화 3. 반복 수행되는 액세스 경로의 해결 • 데이터량이 많은 경우 검토(초기에는 적용하기 쉬우나 운영 중에는 초기에 비해 적용이 어려움) 4. 클러스터링 검토 • 컬럼의 순서를 결정 5. 인덱스 컬럼의 조합 및 순서의 결정 • 잘못된 쿼리로 인해 인덱스 적용이 안 될 수 있음. 이런 쿼리들을 최적화 쿼리로 수정 • 모든 작업이 완료되면 일괄 적용 6. 시험생성 및 테스트 그리고 일괄 수정
  • 21. INDEX 활용기준 결합 INDEX 순서 절차  항상 사용하는가 ?  항상 EQUAL로 사용되는가?  분포도가 좋은 컬럼 우선  SORT 순서는?  어떤 컬럼을 추가?(후보선수)
  • 22. 추가된 인덱스가 미치는 영향 SELECT * FROM TAB1 WHERE A = '10' AND B = ‘130415' AND C = '123' AB C INDEX1 INDEX2 A = '10‘ B = ‘130415' C = '123' (INDEX1 사용) D column 추가 ABD C INDEX1 INDEX2 C = '123' (INDEX2 사용) A = '10‘ B = ‘130415‘ D LIKE ‘A%’
  • 23. 추가된 인덱스가 미치는 영향 예제 CHULITEM table Primary Key : CHULNO + ORDNO + ITEM SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY FROM CHULITEM WHERE CHULNO = '2565' AND ORDNO = '8584' AND LOT = 'P0009' 1 rows, 0.01sec TABLE ACCESS BY ROWID CHULITEM INDEX RANGE SCAN PK_CHULITEM SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY FROM CHULITEM WHERE CHULNO = '2565' AND ORDNO = '8584' AND LOT = 'P0009' 1 rows, 37.7sec SQL> CREATE INDEX CI_LOT ON CHULITEM (LOT) TABLE ACCESS BY ROWID CHULITEM INDEX RANGE SCAN CI_LOT SQL> SELECT CHULNO, ORDNO, ITEM, CHULQTY FROM CHULITEM WHERE CHULNO = '2565' AND ORDNO = '8584' AND LOT = 'P0009' 1 rows, 0.01 sec SQL> CREATE INDEX CI_LOT_ITEM ON CHUITEM (LOT,ITEM) TABLE ACCESS BY ROWID CHULITEM INDEX RANGE SCAN PK_CHULITEM
  • 25. JOIN 기본 실력 Test 조인에 대한 이해 문제 상품명을 가져 올 때 어떤 방법이 비용을 절약 할 수 있는 방법인가? 상품 테이블(100건) 상품번호 (PK) 상품명 VARCHAR2(4BYTE) 주문 테이블(10만건) 주문번호 (PK) 상품번호(FK) ①상품테이블에 상품명을 추가해서 주문테이블과 조인해서 검색 SELECT * FROM 주문, 상품 WHERE 주문.상품번호 = 상품.상품번호 주문 테이블(10만건) 주문번호 (PK) 상품명 VARCHAR2(4BYTE) ②주문테이블에 상품명을 추가해서 주문테이블만 검색 SELECT * FROM 주문 상품명 컬럼 4byte를 추가하게 되면 1Row는 4x100,000 = 400,000 상품명 컬럼 4byte를 추가하게 되면 1Row는 4x100 = 400
  • 26. 수행속도의 결정요소 DRIVING! TAB2 K . . . . . . . A . . . . . . . . . . . . . . . D . . . . . . . Z . . . . . . . KEY2 FLD . . . FLD . . . KEY1 . . . . . . . . . A . . . . . . . . . D . . . . . . . . . B . . . . . . . . . . . . . . . . . . . K K . . . . . . . A . . . . . . . . . . . . . . . D . . . . . . . Z . . . . . . . KEY2 FLD . . . . . . . . . . . . A . . . . . . . . . D . . . . . . . . . B . . . . . . . . . . . . . . . . . . . K FLD . . . KEY1 INDEX 있음 TAB1 INDEX 있음 TAB1 TAB2 INDEX 있음 INDEX 없음 -인덱스가 한쪽만 있으면 FULL SCAN이 발생 -두쪽 다 인덱스가 없으면 SORT MERGE 방법으로 처리
  • 27. ACCESS량에 따른 처리 속도  ACCESS량이 많음 운반 단위 INDEX (FLD1) TAB1 TAB2INDEX (KEY2) FLD1='10' KEY2 = KEY1 o x 5000 row x x x x . . . . 100 row 50 row . . . . . . . . x o o FLD2 like ‘A%’  ACCESS량이 적음 운반 단위 INDEX (FLD2) INDEX (KEY1) KEY1 = KEY2 FLD2 like 'A%' 100 row . . . . 70 row50 row . . . . . . . . . . . . x TAB1 TAB2 o o FLD1 =‘10’ SELECT A.FLD1, ..., B.FLD1,... FROM TAB2 B, TAB1 A WHERE A.KEY1 = B.KEY2 AND B.FLD2 like 'A%' AND A.FLD1 = '10' 15 Sec 1 Sec
  • 28. ACCESS량에 따른 처리 속도 ACCESS량이 많은 방식을 ACCESS량이 적은 방식으로 실행되게 하려면 위 쿼리를 어떻게 변경 해야 할까요?
  • 29. JOIN과 LOOP QUERY JOIN LOOP-QUERY 운반 단위 SQL SQL SQL TAB1 TAB2 . . . . SQL SQL 2 차 가 공 . . . . . . . . 2 차 가 공 운반 단위 TAB1 TAB2 . . . . . . . . . . . .
  • 30. for(i = 0; i < 100; i++){ for(j = 0; j < 100; j++){ // Do Anything.. } } Nested Loops 조인 Nested Loops = For 문
  • 31. Nested Loops 조인 운반 단위 INDEX (FLD1) TAB1 TAB2 INDEX (KEY2) FLD1= 'AB' TABLE ACCESS BY ROWID KEY2 = KEY1 TABLE ACCESS BY ROWID FLD2 ='10' check o o o x SELECT A.FLD1, ..., B.FLD1,... FROM TAB1 A, TAB2 B WHERE A.KEY1 = B.KEY2 AND A.FLD1 = 'AB' AND B.FLD2 = '10' • 모든 DBMS에서 사용 • 부분범위처리 가능 • 먼저 처리되는 테이블의 처리범위에 따라 처리량 결정 • 랜덤(Random) 액세스 위주 • 연결고리 상태에 따라 영향이 큼 • 주로 좁은 범위 처리에 유리
  • 32. Nested Loops 조인 SELECT /*+ ORDERED USE_NL(E) */ E.EMPNO, E.ENAME, D.DNAME, E.JOB, E.SAL FROM DEPT D, EMP E WHERE E.DEPTNO = D.DEPTNO …………… ① AND D.LOC = 'SEOUL' …………… ② AND D.GB = '2' …………… ③ AND E.SAL >= 1500 …………… ④ ORDER BY SAL DESC * pk_dept : dept.deptno * dept_loc_idx : dept.loc * pk_emp : emp.empno * emp_deptno_idx : emp.deptno * emp_sal_idx : emp.sal 인덱스 구조 문제! 조건 비교 순서가 어떻게 사용될까요? Execution Plan --------------------------------------------------- 0 SELECT STATEMENT 1 0 SORT ORDER BY 2 1 NESTED LOOPS 3 2 TABLE ACCESS BY INDEX ROWID DEPT 4 3 INDEX RANGE SCAN DEPT_LOC_IDX 5 2 TABLE ACCESS BY INDEX ROWID EMP 6 5 INDEX RANGE SCAN EMP_DEPTNO_IDX ② → ③ → ① → ④
  • 33. Nested Loops 조인 SELECT /*+ ORDERED USE_NL(E) */ E.EMPNO, E.ENAME, D.DNAME, E.JOB, E.SAL FROM DEPT D, EMP E WHERE E.DEPTNO = D.DEPTNO …………… ③ AND D.LOC = 'SEOUL' …………… ① AND D.GB = '2' …………… ② AND E.SAL >= 1500 …………… ④ ORDER BY SAL DESC ① ② D.LOC = ‘SEOUL’의 범위가 넓으면 전체적인 속도 저하 발생 체크조건인 D.GB = ‘2’ 범위가 넓으면 결합인덱스 고려 ③ ④ E.DEPTNO, D.DEPTNO 각 컬럼이 데이터 타입이 일치하는지 확인 DRIVING 될 E.DEPT_NO에 인덱스가 있는지 확인 E.SAL 범위가 넓으면 결합인덱스 고려 NL JOIN이 효과적이지 못 할 때 HASH JOIN, SORT MERGE JOIN 고려
  • 34. Nested Loops 조인 • 블록단위로 I/O를 수행 • 하나의 레코드만 읽어도 블록을 통째로 읽음 • RANDOM ACCESS는 빠르지만 비효율이 존재 대량의 데이터를 조인할 때 비효율적 • 대용량 데이터 처리 시 매우 치명적인 한계를 보임 • 대용량이더라도 부분범위 처리 상황에서 빠른 속도를 낼 수 있음 순차적 조인 • 다른 조인방식과 비교 했을 때 인덱스 구성 전략이 중요 • 소량의 데이터를 처리 할 때 효율적 • Prefetch(Table,Index), Buffer Pinning 효과로 액세스 획기적 감소 (Non unique) • 가능한 Nested Loop방식으로 처리하고 비효율적일 때 Hash 조인과, Merge 조인 고려 온라인 환경에 적합한 조인 Nested Loop 특징
  • 35. 각 테이블을 조건에 맞게 정렬 한 후 Merge Sort Merge 조인 운반단위 . . . S O R T . . . . . . . . . . . . S O R T . . . . . . . . .
  • 36. Sort Merge 조인 효율적인SQL 방법 옵티마이져 사용자 Nested Loop로 처리해 쓸만한 인덱스가 있나?.. 없네;; 소트머지 조인이나 해쉬 조인을 써야겠다~
  • 37. Sort Merge 조인 SELECT /*+USE_MERGE(A,B)*/ A.FLD1, ..., B.FLD2,... FROM TAB1 A, TAB2 B WHERE A.KEY1 = B.KEY2 AND A.FLD1 = 'AB' AND B.FLD2 = '10' INDEX (FLD1) TAB1 TAB2 FLD1= 'AB' TABLE ACCESS BY ROWID 운반단위 . . . S O R T INDEX (FLD2) FLD2= '10' TABLE ACCESS BY ROWID a.KEY1= b.KEY2 를 조건으로 Merge . . . . . . . . . . . . S O R T . . . . . . . . . • 전체범위 처리 (First, Second) • 인덱스 유무에 영향을 받지 않음 • 주로 넓은 범위 처리에 유리 • 조인 컬럼에 인덱스가 없을 때 유리 • NL과 같은 스캔 액세스 위주 • PGA에있는 SQLAREA 사용하여 래치 획득 과정이 없음
  • 38. Sort Merge 조인 Sort Merge(뭐지?) 단계 1. Sort 단계 : 양쪽 집합을 조인 컬럼 기준으로 정렬 2. Merge 단계 : 정렬된 양쪽 집합을 서로 머지 Point !! 정렬해서 merge한다는 점만 다를 뿐 수행과정은 Nested Loop와 다르지 않음 왜? Sort Area 때문에~ = SORT!
  • 39. PGA <- SQL AREA ORACLE에서 사용 하는 메모리 SGA : 모든 서버 및 백그라운드 프로세스에 의해 공유 PGA : 각 서버 프로세스에 대한 데이터 및 제어정보를 포함 공용으로 쓰는 메모리 독립적으로 사용되는 메모리
  • 40. Sort Merge 조인 같이 사용 하는 공간 모든 유저에게 할당하는 각각의 프로세스가 독점으로 사용하는 공간
  • 41. Sort Merge 조인 정렬공간 (Sort Area) 세션정보 커서상태 정보 변수저장 공간 ORDER BY GROUP BY ROLLUP DISTINCT UNION MINUS INSERT SELECT 인덱스 생성 BITMAP 연산 수행 SORT MERGE 조인 HASH JOIN 통계정보 독립적인 메모리 공간이어서 래치 획득 과정이 없어서 빠름
  • 42. Sort Merge 조인 Sort Merge Join…… 언제 어떻게 써야 좋은 거야?
  • 43. Sort Merge 조인 First 테이블에 소트 연산을 대체할 인덱스가 있을 때 CREATE INDEX dept_idx ON dept(loc, deptno); CREATE INDEX emp_idx ON emp(job, deptno); 인덱스 생성 SELECT /*+ ordered use_merge(e) */ * FROM dept d, emp e WHERE d.deptno = e.deptno AND d.loc = 'CHICAGO’ AND e.job = 'SALESMAN’ ORDER BY e.deptno; 쿼리 실행 실행 계획 SORT 오퍼레이션 줄이기!! FIRST 테이블 부분범위 처리 유도하
  • 44. Sort Merge 조인 조인할 First 집합이 이미 정렬돼 있을 때 GROUP BY, ORDER BY, DISTINCT를 이용해서 이미 정렬 된 경우 효율적! SELECT /*+ ORDERED USE_MERGE(D) */ D.DEPTNO, D.DNAME, E.AVG_SAL FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROM EMP GROUP BY DEPTNO) E , DEPT D WHERE E.DEPTNO = D.DEPTNO 10g R2에서 도입된 hash group by로 효율이 낮아 지기 때문에 Sort group by로 유도 해야 함! 쿼리 실행 쿼리 실행
  • 45. Sort Merge 조인 조인할 First 집합이 이미 정렬돼 있을 때 GROUP BY, ORDER BY, DISTINCT를 이용해서 이미 정렬 된 경우 효율적! SELECT /*+ ORDERED USE_MERGE(D) */ D.DEPTNO, D.DNAME, E.AVG_SAL FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROMEMP GROUP BY DEPTNO ORDER BY DEPTNO) E , DEPT D WHERE E.DEPTNO = D.DEPTNO 9i 에서는 Sort group by로 처리 됨(hash group by가 없음) 쿼리 실행 쿼리 실행
  • 46. Sort Merge 조인 조인 조건식이 등치(=) 조건이 아닐 때 Hash 조인은 = 조건만 사용 가능 하지만 merge조인은 between, <, <=, >, >= 조건도 사용가능! SELECT /*+ ORDERED USE_MERGE(E) */ D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME FROM DEPT D, EMP E WHERE D.DEPTNO <= E.DEPTNO WHERE D.DEPTNO >= E.DEPTNO ASC DESC
  • 47. NESTED LOOP, SORT MEGE JOIN 예제 MERGE JOIN SORT JOIN TABLE ACCESS FULL CHULGOT SORT JOIN TABLE ACCESS FULL CUSTOMER SQL> SELECT X.CUSTNO,CHULDATE, CUSTNAME FROM CHULGOT X, CUSTOMER Y WHERE X.CUSTNO = Y.CUSTNO 5.44 sec NESTED LOOPS TABLE ACCESS FULL CHULGOT TABLE ACCESS BY ROWID CUSTOMER INDEX UNIQUE SCAN PK_CUSTNO 0.02 sec SORT GROUP BY MERGE JOIN SORT JOIN TABLE ACCESS FULL CHULGOT SORT JOIN TABLE ACCESS FULL CUSTOMER SQL> SELECT NATION, SUM(CHULTIME) FROM CHULGOT X, CUSTOMER Y WHERE X.CUSTNO = Y.CUSTNO GROUP BY NATION 8.33 sec SQL> SELECT /*+ RULE */ NATION, SUM(CHULTIME) FROM CHULGOT X, CUSTOMER Y WHERE X.CUSTNO = Y.CUSTNO GROUP BY NATION SORT GROUP BY NESTED LOOPS TABLE ACCESS FULL CUSTOMER TABLE ACCESS BY ROWID CHULGOT INDEX RANGE SCAN CH_CUSTNO 17.5 sec
  • 48. JOIN 방법의 결정 Nested Loop JOIN 좁 다 넓 다 Driving table 결정 부 분 범 위 처 리 Check 조건 Sort Merge JOIN 넓 다 좁 다 가 능 불가능 유 리 불 리 Driving 과 Check 조건 교환 가 능 Driving 조건 First_rows 불가능 상수를 추가로 넣는게 유리한지 비교 All_rows
  • 49. Hash 조인 Nested loop, Sort merge join의 대안 HASH JOIN 7.3
  • 50. HASH JOIN 원리 2개 테이블 중 작은 집합을 HashMap으로 생성 큰 집합을 읽어서 해시테이블을 탐색하며 조인 -Nested Loop Join처럼 Random액세스 부하가 없음. -Sort Merge Join처럼 미리 양쪽 집합을 정렬하는 부담이 없음. -Hash 테이블 생성 시 많은 COST가 발생됨. -Hash Area에 담길 정도의 크기로 만들어져야 성능이 향상 됨.
  • 51. Hash Join Build Input 옵티마이저의 실수
  • 52. HASH JOIN 원리 SELECT /*+USE_HASH(D E) */ D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME FROM SCOTT.DEPT D, SCOTT.EMP E WHERE D.DEPTNO = E.DEPTNO; SELECT /*+LEADING(E) USE_HASH(D E) */ D.DEPTNO, D.DNAME, E.EMPNO, E.ENAME FROM SCOTT.DEPT D, SCOTT.EMP E WHERE D.DEPTNO = E.DEPTNO;
  • 53. HASH JOIN 원리 효율적인 SQL작성방 법 HASH AREA가 초과 될 때 옵티마이저의 생각 읽기 Grace 해시 조인 > Hybrid 해시 조인 / Recursive 해시 조인 (Nested Loop 해시 조인)
  • 54. HASH JOIN 원리 Build input 키 값 중복이 많이 발생할 때 튜닝 방법 SELECT /*+USE_HASH(O F) */ COUNT(*) FROM ORDER O, CONTRACT F WHERE O.PRODUCT_CD = F.PRODUCT_CD AND O.ORDER_DT = F.CONTRACT_DT AND O.ORDER_NO IN (F.ORDER_NO_BUY, F.ORDER_NO_SELL); AND F.CONTRACT_DT = :주문일자 SELECT /*+ GATHER_PLAN_STATISTICS USE_HASH(O F) */ COUNT(*) FROM ORDER O, (SELECT PRODUCT_CD, FILL_DT, ORDER_NO_BUY AS ORDER_NO FROM CONTRACT UNION ALL SELECT PRODUCT_CD, FILL_DT, ORDER_NO_SELL AS ORDER_NO FROM CONTRACT) F WHERE O.PRODUCT_CD = F.PRODUCT_CD AND O.ORDER_DT = F.CONTRACT_DT AND O.ORDER_NO = F.ORDER_NO AND F.CONTRACT_DT = :주문일자 71초 0.16초
  • 55. HASH JOIN 원리 HASH JOIN 사용 기준 한 쪽 테이블이 Hash Area에 담겨야 함. Build Input 해시 키 컬럼에 중복 값이 거의 없어야 함. 조인 컬럼에 적당한 인덱스가 없어 NL조인이 비효율적일 때 조인 액세스량이 많아 Random 액세스 부하가 심할 때 소트머지조인을 하기에는 두 테이블이 너무 클 때 수행빈도가 낮고 쿼리 수행 시간이 오래 걸리는 대용량테이블 조인 할 때
  • 57. Outer NL Join, Outer Sort Merge Join Outer join의 함정 문제 Optimizer는 고객 테이블, 주문 테이블 중 어느 테이블을 먼저 Driving 할 것인가? 고객 테이블(100건) 고객번호 (PK) 주문테이블(1,000만건) 주문번호(PK) 고객번호(FK) SELECT * FROM 고객, 주문 WHERE 고객.고객번호(+) = 주문.고객번호 고객테이블이 먼저 Driving 되어야 하지만 Outer 조건 때문에 주문 테이블을 먼저 Driving 하게 됨. (키 존재 여부를 Outer가 아닌쪽을 전체 조 회 해봐야 알 수 있기 때문에) (+)기호가 붙지 않은 테이블이 먼저 드라이빙!!
  • 58. Outer Join 제거 예제 튜닝 전 튜닝 후
  • 60. Outer Hash Join 매칭된 레코드는 결과집합에 삽입 매칭되지 않은 레코드는 마지막에 붙임
  • 61. Left Outer 조인 + Union All + Anti 조인(Not Exists) Full Outer Join SELECT A.고객ID, A.입금액, B.출금액 FROM (SELECT 고객ID, SUM(입금액) 입금액 FROM 입금 GROUP BY 고객ID)A ,(SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID)B WHERE B.고객ID(+)=A.고객ID UNION ALL SELECT 고객ID, NULL, 출금액 FROM (SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID) A WHERE NOT EXISTS (SELECT 'X' FROM 입금 WHERE 고객ID=A.고객ID); SELECT NVL(A.고객ID, B.고객ID) 고객ID, A.입금액, B.출금액 FROM (SELECT 고객ID, SUM(입금액) 입금액 FROM 입금 GROUP BY 고객ID) A FULL OUTER JOIN (SELECT 고객ID, SUM(출금액) 출금액 FROM 출금 GROUP BY 고객ID) B ON A.고객ID=B.고객ID;
  • 62. 일반 SELECT문과 전혀 다른 CONNECT BY!!
  • 63. 순환관계(CONNECT BY) ID . . . . P_ID A . . . B . . . A C . . . A D . . . B E . . . B G . . . D F . . . C H . . . F J . . . F 순 환 전 개 법 A B C D E F H JG 구조(순환관계)가 변경 되도 식별자는 변하지 않음 잘 못 사용 시 수행속도 저하 1000 1100 1200 1110 1120 1210 1211 12121111 ID . . . . 1000 . . . 1100 . . . 1110 . . . 1111 . . . 1120 . . . 1200 . . . 1210 . . . 1211 . . . 1212 . . . 사용하기가 쉽고 간편하며 수행속도에 상대적으로 유리함 구조 변경에 매우 취약함 (식별자 변경) 구조 변경 시 과거 데이터의 수정이 필요함 C O D E 대 비 법
  • 64. 순환관계(CONNECT BY) CONNECT BY SQL GENERAL SQL SELECTSELECT LEVELLEVEL , COL1, COL2,......, COL1, COL2,...... SEUDO 컬럼 SELECT COL1, COL2,...... JOIN 테이블 FROM TAB1 (동일테이블로 조인 간주) FROM TAB1 x, TAB2 yFROM TAB1 x, TAB2 y WHERE conditions . . . . . .WHERE conditions . . . . . . AND check_conditions . . . . . . CHECK 조건 JOIN 조건 CONNECT BYCONNECT BY PRIORPRIOR ID = P_IDID = P_ID and conditions . . .and conditions . . . WHEREWHERE x. KEY = y.KEYKEY = y.KEY 선처리 테이블 조건 START WITH conditions AND driving_table_conditions 선처리테이블 ALIAS
  • 65. 순환관계(CONNECT BY) 활용 SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . . FROM BOM CONNECT BY PRIOR ID = P_ID AND ID <> ‘F’ START WITH P_ID = ‘A’ 특 정 경 우 만 미 추 출예 하 그 룹 미 전 개 SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . . FROM BOM WHERE ID <> ‘F’ CONNECT BY PRIOR ID = P_ID START WITH P_ID = ‘A’ A C F H J B D E G A C F H J B D E G
  • 66. 순환관계(CONNECT BY) ID . . . . P_ID A . . . B . . . A C . . . A D . . . B E . . . B G . . . D F . . . C H . . . F J . . . F 순 환 전 개 법 A B C D E F H JG 최상위 P_ID는 널로 만들지 않는다. 최상위에 무의미한 ROW를 추가해서 효율을 높인다. ROOT | NULL | NULL
  • 67. 순환관계(CONNECT BY) 활용 SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . . FROM BOM CONNECT BY PRIOR ID = P_ID AND T_ID = 1 START WITH P_ID = ‘1000’ AND T_ID = 1 전 체 집 합 순 환 관 계소 그 룹 별 순 환 관 계 1000 1100 1200 1110 1120 1210 1211 12121111 T_ID = 1 1000 1100 1200 1110 1120 1210 1211 12121111 T_ID = 2 1000 1100 1200 1110 1120 1210 1211 12121111 T_ID = 3 A E F H JG 1 B2 DF K G C P H O SELECT LPAD(‘ ‘, 2*LEVEL)||COL1. . . . FROM BOM CONNECT BY PRIOR ID1 = P_ID1 AND PRIOR ID2 = P_ID2 START WITH P_ID1 = ‘A’ AND P_ID2 = ‘10’
  • 68. 시내 주행 1등급 연비 스칼라 서브쿼리!
  • 69. 스칼라 서브쿼리 SELECT (SELECT B.NAME FROM DEPT B WHERE B.DEPT_NO = A.EMP_NO) FROM EMP_NO A 출력 값 : B.NAME 입력 값 : A.EMP_NO Cache
  • 70. 스칼라 서브쿼리 SELECT GET_USER_AMT(A.EMP_ID) FROM EMP_NO A, ……… SELECT (SELECT GET_USER_AMT(A.EMP_ID) FROM DUAL) FROM EMP_NO A, ……… 함수 입력 값의 종류가 적을 수록 효율적 캐시 사이즈가 부족하여 해시 충돌이 발생하면 엄청난 부하를 발생 시킴!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  • 71. 스칼라 서브쿼리(해시 충돌 제어 방법) SELECT (SELECT GET_USER_AMT(A.EMP_ID) FROM DUAL) FROM EMP_NO A, ……… 해시 충돌이 발생하면 기존 엔티리를 밀어내고 새로운 엔트리 생성이 반복되면서 성능부하 발생! 캐시 사이즈 증가로 해시 충돌 방지! ALTER SESSION SET “_query_execution_cache_max_size” = 3000000; 45초 0.79초
  • 72. ERD
  • 73. EXPLAIN PLAN ID OPERATION OPTIONS OBJECT_NAME 1 FILTER 2 NESTED LOOPS 3 TABLE ACCESS FULL EMP 4 TABLE ACCESS BY ROWID DEPT 5 INDEX UNIQUE SCAN PK_DEPT 6 TABLE ACCESS FULL SALGRADE 1 2 6 FILTER NESTED LOOPS TABLE ACCESS (FULL) salgrade 3 4 TABLE ACCESS (FULL) emp TABLE ACCESS (BY ROWID) dept 5 INDEX (UNIQUE SCAN) pk_dept SELECT ename, job, sal, dname FROM emp, dept WHERE emp.deptno = dept.deptno AND not exists (SELECT 1 FROM salgrade WHERE emp.sal BETWEEN losal AND hisal)

Editor's Notes

  1. Statement, prestatement 바인딩 단점을 보완한 바인딩변수 peeking : 하드파싱 시 컬럼분포도를 이용해 통계정보를 만들어낸다 -SQL 파서가 파싱 반복사용하기 위해 라이브러리 캐쉬에 저장( 커서 공유) -최적화하기 쉬운형태로 변환 후보군이 될만한 실행계획들 생성 오브젝트 통계정보, 시스템 성능 통계정보를 이용하여 필요한 I/O, CPU, 메모리 사용량 등을 예측 -SQL 실행계획 생성
  2. 조인 시 가장 먼저 확인 해야 할 부분은 조인이 될 키에 인덱스가 있는지 입니다. 인덱스가 없게 되면 무조건 FULL SCAN을 유발 시키게 됩니다.
  3. 성능 저하는 DB 커넥션과 I/O 사이즈입니다. LOOP–QUERY는 많은 DB 커넥션을 발생 시킵니다. 하지만 LOOP QUERY가 무조건 안좋은건 아닙니다.
  4. DRIVING TABLE 결정 (부분범위처리가 가능 한지 부가능 한지) 부분범위 처리가 가능 하다면 DRIVING 조건 확인 CHECK조건이 넓으면 블록에 담는 속도가 빠르기 때문에 NESTED 푼다. CHECK조건이 DRVING 조건 보다 더 똑똑해서 범위를 줄 일수 있는지 확인 1.부분범위 처리가 불가능 하다면 상수를 받은게 유리한지 받아봐야 별 효율이 없는지 확인
  5. 11g에서 Native Hash Full Outer조인 기능 추가
  6. 11g에서 Native Hash Full Outer조인 기능 추가
  7. CODE 대비법을 사용 할 경우에는 절때 구조가 변경되지 않는다는 전재 조건이 있어야 합니다. CODE 대비법은 RDB 규칙을 깨는 방법입니다. 하지만 속도는 순환전개법에 대비해서 빠릅니다.
  8. 순환관계 쿼리 CONNECT BY 와 일반 SQL 쿼리는 다릅니다. 같은 쿼리로 착각 하지마세요.
  9. 순환관계에서 필터링은 원리를 이해하셔야 합니다. WHERE 절이 필터링 조건이고 CONNECT BY 절이 DRIVING 조건입니다.
  10. 최상위 부터 전개시 ROOT에 PID가 NULL이면 전체건을 다 읽은 후에 순환관계가 이뤄지기 때문에 비효율적 입니다.
  11. 11g에서 Native Hash Full Outer조인 기능 추가
  12. 11g에서 Native Hash Full Outer조인 기능 추가
  13. 11g에서 Native Hash Full Outer조인 기능 추가