오라클 데이터베이스 성능 튜닝.

Slides:



Advertisements
Similar presentations
강사: 이종인 다우 교육원 전임강사 / 온디멘드 수석 컨설턴트 / FMG 수석 컨설턴트
Advertisements

SQL 언어 SQL.
데이터베이스 9주차 : 데이터베이스 설계 2교시 : 데이터베이스 설계(3)
Allow reverse scans allow reverse scnas. allow reverse scans allow reverse scnas.
SQL Statement Tuning e-Architecture 팀 임성욱.
Nested Queries CSED421: Database Systems Labs.
19.(코드+년도+월)별,(코드)별,전체총액을 한번에
오라클 데이터베이스 성능 튜닝.
Perfect! 대용량 데이터베이스 튜닝Ⅱ.
데이터 모델링 방법론 2003년 03월.
PL/SQL.
Analytic Function Analytic Function의 소개
질의어와 SQL 기본 SQL 고급 SQL 데이타의 수정 데이타 정의 언어 내장 SQL
관계 대수와 SQL.
Second lab (제출기한 : 11월 15일(목) 까지)
대용량 데이터베이스 솔루션 발표자: 박보영 2007년 5월19일.
DataBase 기본 교육 신입사원용 최지철.
Database & Internet Computing Laboratory 한 양 대 학 교
박시우 ( 업무에 바로 쓰는 SQL 튜닝 박시우 (
Chapter 5 SQL: 확장된 질의, 주장, 트리거, 뷰.
제 5 장 인덱스 생성 및 관리.
Execution Plan의 수립 결과 SQL OPTIMIZER SQL해석 실행 계획 실행 수립 참조 참조 추출
SELECT 문 사원 테이블의 모든 정보를 출력하는 예제 1. 비교 연산자 SELECT 문의 형태
4장. 관계 대수와 SQL SQL 관계 데이터 모델에서 지원되는 두 가지 정형적인 언어
SQL-99: 스키마 정의, 기본제약조건, 질의어 충북대학교 구조시스템공학과 시스템공학연구실
7장 조인.
다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL
SQL 개요 SQL 개요 - SQL은 현재 DBMS 시장에서 관계 DBMS가 압도적인 우위를 차지하는 데 중요한 요인의 하나
8장 서브 쿼리.
Toad for Oracle 설치 방법.
오라클 데이터베이스 성능 튜닝.
요약 정보 만들기.
오라클 데이터베이스 성능 튜닝.
kHS 데이터베이스 테이블 및 인덱스 kHS.
롯데마트 CRM 데이터 분석 교육 2014년 12월 > RE::VISION 전용준 리비젼컨설팅 대표
데이터 베이스 설계 및 실습 #3 - SQL 함수.
14장 뷰.
Chapter 05 데이터베이스 프로그래밍.
6장. 물리적 데이터베이스 설계 물리적 데이터베이스 설계
4.2 SQL 개요 SQL 개요 SQL은 IBM 연구소에서 1974년에 System R이라는 관계 DBMS 시제품을 연구할 때 관계 대수와 관계 해석을 기반으로, 집단 함수, 그룹화, 갱신 연산 등을 추가하여 개발된 언어 1986년에 ANSI(미국 표준 기구)에서 SQL.
I. SQL 성능 향상 가이드.
14 뷰(View) 뷰의 개념 뷰 관리.
제 17 장 (Oracle) 오라클에서 질의 최적화
뷰와 저장 프로시저 뷰의 개념을 이해한다. 뷰의 정의와 관리 방법을 이해한다. 뷰를 사용함으로써 생기는 장점을 알아본다.
SELECT empno, ename, job, sal, dname FROM emp, dept
3장 SQL*Plus 명령어.
9장 테이블 생성 및 변경, 삭제하기(DDL).
DP-ORA 쿼리 최적화 가이드 쿼리 최적화 방법 2014년 7월.
SQL.
Quiz #1.
강사: 이종인 다우 교육원 전임강사 / 온디멘드 수석 컨설턴트 / FMG 수석 컨설턴트
SQL Server 7.0 세미나 (Performance Tuning)
다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL
Chapter 3: Introduction to SQL
다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL
CHAPTER 06. 데이터베이스 자료의 조직적 집합체_데이터베이스 시스템의 이해
13장 무결성 제약조건.
View(뷰) 1 가상 테이블(Virtual Relation)
데이터베이스 (Database) SQL 추가 기능: 주장, 뷰, 프로그래밍 기법 문양세 강원대학교 IT대학 컴퓨터과학전공.
Database 중고차 매매 DB 비즈니스IT 윤동섭.
11장. GROUP BY와 HAVING 열의 그룹화 2개 이상의 열에 대한 그룹화
오라클 쿼리 문제 EMP (사원 테이블) DEPT (부서 테이블) 컬럼명 설명 EMPNO 사원번호 ENAME 사원명 JOB
기본적인 SELECT문 작성.
8장 테이블의 생성 및 변경 정인기.
SQL Tuning.
문양세 (1st version: 문성우) (revised by 손시운)
4.DECODE 함수를 이용한 IF 처리의 효율화
06. SQL 명지대학교 ICT 융합대학 김정호.
How I Approach Tuning a SQL Statement
Stored program 장종원
Presentation transcript:

오라클 데이터베이스 성능 튜닝

데이터 생성 인덱스 테이블 인덱스 데이터 값을 정렬하여 기록 들어오는 순서대로 기록 고객번호 이름 생일 이름 ROWID 고객번호 이름 생일 이름 ROWID A page 7 109 D 90/01 C page 3 108 K 90/01 D page 1 102 C 92/05 D page 4 103 D 92/06 F page 5 104 F 93/01 K page 8 105 93/10 K page 2 101 A 93/10 page 6 100 K 93/10

테이블 액세스(인덱스 없는 경우) ① Filter WHERE 이름 = ‘K’ 고객번호 이름 생일 X O 고객번호 이름 생일 100 D 90/01 X 101 K 90/01 O FULL TABLE SCAN 102 C 92/05 X 103 D 92/06 X 104 F 93/01 X 105 X 93/10 X 106 A 93/10 X 107 K 93/10 O

테이블 액세스(인덱스 있는 경우) Access WHERE 이름 = ‘K’ INDEX SCAN TABLE ACCESS BY ROWID 이름 ROWID 고객번호 이름 생일 A page 7 100 D 90/01 C page 3 101 K 90/01 D page 1 102 C 92/05 D page 4 103 D 92/06 F page 5 104 F 93/01 K page 8 105 X 93/10 K page 2 106 A 93/10 X X page 6 107 K 93/10

인덱스 사용 기준 인덱스 대상 컬럼 인덱스 사용시 손해보는 경우 조건문에 자주 등장하는 컬럼 같은 값이 적은 컬럼(분포도가 좁은 컬럼) 조인에 참여하는 컬럼 인덱스 사용시 손해보는 경우 데이터가 적은 테이블 같은 값이 많은 컬럼(분포도가 넓은 컬럼) 조회보다 DML의 부담이 큰 경우

결합 인덱스의 사용 결합 인덱스 2개이상의 컬럼이 조건문에 자주 등장시 WHERE 이름 = ‘C’ 2개이상의 컬럼이 조건문에 자주 등장시 WHERE 이름 = ‘C’ AND 생일 > ‘92/12’ 이름 생일 ROWID 고객번호 이름 생일 A 93/10 page 7 109 C 94/01 C 92/05 page 3 108 K 90/01 C 93/01 page 5 102 C 92/05 C 93/10 page 6 103 D 92/06 C 94/01 page 1 104 C 93/01 X D 92/06 page 4 105 C 93/10 K 90/01 page 2 101 A 93/10 K 93/10 page 8 100 K 93/10

결합 인덱스의 사용 결합 인덱스 인덱스만으로도 결과를 얻을 수 있을때 ... SELECT 이름, 생일 FROM 고객테이블 WHERE 이름 = ‘C’ AND 생일 > ‘92/12’ 결합 인덱스 인덱스만으로도 결과를 얻을 수 있을때 ... 이름 생일 ROWID 고객번호 이름 생일 A 93/10 page 7 109 C 94/01 C 92/05 page 3 108 K 90/01 C 93/01 page 5 O 102 C 92/05 C 93/10 page 6 O 103 D 92/06 C 94/01 page 1 O 104 C 93/01 X D 92/06 page 4 105 C 93/10 K 90/01 page 2 101 A 93/10 K 93/10 page 8 100 K 93/10

결합인덱스 사용 기준 결합인덱스를 사용하는 경우 결합인덱스의 컬럼 순서 자주 조건에 같이 등장하는 경우 인덱스만 읽고도 결과를 얻을 수 있을 때 결합인덱스의 컬럼 순서 사용빈도가 높은 컬럼부터 SCAN 범위를 줄여주는 컬럼부터 자주 사용되는 컬럼부터

스캔범위결정 조건과 검증조건 WHERE 이름 = ‘C’ AND 생일 > ‘92/12’ AND 고객번호 = 105 인덱스 범위결정 Filter 이름 생일 ROWID 고객번호 이름 생일 A 93/10 page 7 109 D 90/01 C 92/05 page 3 108 K 90/01 C 93/01 page 5 102 C 92/05 C 93/10 page 6 103 D 92/06 X D 90/01 page 1 104 C 93/01 O X D 92/06 page 4 105 C 93/10 K 90/01 page 2 101 A 93/10 K 93/10 page 8 100 K 93/10

스캔범위결정 조건과 검증조건 Filter Filter Access 범위결정 WHERE 이름 = ‘C’ AND 생일 like ‘%10’ AND 고객번호 = 105 Access 범위결정 Filter Filter 이름 생일 ROWID 고객번호 이름 생일 A 93/10 page 7 109 D 90/01 C 92/05 page 3 X 108 K 90/01 C 93/10 page 5 102 C 92/05 C 93/10 page 6 103 D 92/06 X D 90/01 page 1 104 C 93/01 X D 92/06 page 4 105 C 93/10 O K 90/01 page 2 101 A 93/10 K 93/10 page 8 100 K 93/10

인덱스를 사용하지 못하는 경우 인덱스 컬럼에 변형이 일어난 경우 부정형으로 조건을 기술한 경우 NULL을 비교하였을 경우 내부적인 변형이 일어난 경우 옵티마이져의 판단에 따라 (cost-based optimizer)

인덱스 컬럼의 변형 Select … from department where max_salary * 12 > 2500; max_salary ROWID 부서번호 부서명 max_salary 100 xxxx.xxxx.xxxxxxxx 109 D 150 X 100 xxxx.xxxx.xxxxxxxx 108 K 180 X 150 xxxx.xxxx.xxxxxxxx 102 C 100 X 180 xxxx.xxxx.xxxxxxxx 103 D 200 X 200 xxxx.xxxx.xxxxxxxx 104 C 100 X 200 xxxx.xxxx.xxxxxxxx 105 C 350 O 300 xxxx.xxxx.xxxxxxxx 101 A 200 X 350 xxxx.xxxx.xxxxxxxx 100 K 300 O

인덱스 컬럼의 변형 Select … from department where max_salary > 2500/12 ; 부서번호 ROWID 부서번호 부서명 max_salary 100 xxxx.xxxx.xxxxxxxx 109 D 150 100 xxxx.xxxx.xxxxxxxx 108 K 180 150 xxxx.xxxx.xxxxxxxx 102 C 100 180 xxxx.xxxx.xxxxxxxx 103 D 200 200 xxxx.xxxx.xxxxxxxx 104 C 100 200 xxxx.xxxx.xxxxxxxx 105 C 350 O 300 xxxx.xxxx.xxxxxxxx 101 A 200 350 xxxx.xxxx.xxxxxxxx 100 K 300 O

부정형 조건 Select … from Employee_TEMP where 부서번호 <> ’100’ ; 부서번호 ROWID 부서번호 부서명 max_salary 99 xxxx.xxxx.xxxxxxxx 99 D 150 O 100 xxxx.xxxx.xxxxxxxx 100 K 180 X 100 xxxx.xxxx.xxxxxxxx 100 C 100 X 100 xxxx.xxxx.xxxxxxxx 100 D 200 X 100 xxxx.xxxx.xxxxxxxx 100 C 100 X 100 xxxx.xxxx.xxxxxxxx 100 C 350 X 100 xxxx.xxxx.xxxxxxxx 100 A 200 X 101 xxxx.xxxx.xxxxxxxx 101 K 300 O

부정형 조건 Select … from Employee_TEMP where 부서번호 < ‘100’ OR 부서번호 > ‘100’ ; max_salary ROWID 부서번호 부서명 max_salary 99 xxxx.xxxx.xxxxxxxx 99 D 150 O 100 xxxx.xxxx.xxxxxxxx 100 K 180 100 xxxx.xxxx.xxxxxxxx 100 C 100 100 xxxx.xxxx.xxxxxxxx 100 D 200 100 xxxx.xxxx.xxxxxxxx 100 C 100 100 xxxx.xxxx.xxxxxxxx 100 C 350 100 xxxx.xxxx.xxxxxxxx 100 A 200 101 xxxx.xxxx.xxxxxxxx 101 K 300 O

NULL 비교 Select … from Employee where 생일 is not null; Select …

내부변형 Select … from Employee where 부서번호 = :A (상수) Select … where 부서번호 = to_char( :A) Select … from Employee where 생일 = to_char( :B, ‘yyyymmdd’) Select … from Employee where 생일 = :B (일자)

SQL의 활용 1. EXISTS 대신 JOIN 의 사용 SELECT … FROM EMP E WHERE EXISTS (SELECT 'X' FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND D.DEPT_CAT = 'A'); JOIN 사용문장 SELECT ENAME .. FROM DEPT D, EMP E WHERE E.DEPT_NO = D.DEPT_NO AND D.DEPT_CAT = 'A';

SQL의 활용 2. IN 대신 EXISTS 의 활용 ERD 상에서 base가 되는 테이블에 대한 query는 select할 때 여러 테이블과 join을 하는 경우가 많다. 이러한 경우 IN과 Sub-query를 사용하는 것 보다 EXISTS나 NOT EXISTS를 사용하는 것이 더 나은 성능을 보여주는 경우 IN 사용문장 SELECT * FROM EMP WHERE EMPNO > 7777 AND DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB'); EXISTS 사용문장 SELECT * FROM EMP E WHERE EMPNO > 7777 AND EXISTS (SELECT 'x' FROM DEPT D WHERE D.DEPTNO = E.DEPTNO AND D.LOC = 'MELB');

SQL의 활용 3. NOT IN 대신 NOT EXISTS 의 활용 아래와 같이 Sub-query문에서 NOT IN은 내부적으로 sort와 merge를 수반한다. NOT IN을 사용하면 대체적으로 가장 효율이 나쁜데, 이는 sub-query select에 대상이 되는 테이블을 강제로 full table scan 하도록 하기 때문이다  NOT EXISTS 나 OUT JOIN 문장으로 변경 NOT IN 사용문장 SELECT … FROM EMP WHERE DEPT_NO NOT IN (SELECT DEPT_NO FROM DEPT WHERE DEPT_CAT = 'A'); NOT EXISTS 사용문장 OUTER JOIN 사용문장 SELECT … FROM EMP E WHERE NOT EXISTS (SELECT 'X' FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND D.DEPT_CAT = 'A'); SELECT … FROM EMP A, DEPT B WHERE A.DEPT_NO = B.DEPT_NO (+) AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+) = 'A';

SQL의 활용 4. DISTINCT 대신 EXISTS 의 활용 EMP 테이블 FULL SCAN 1:M 관계에서의 select에서는 EXISTS를 사용해야 한다 DISTINCT 사용문장 SELECT DISTINCT DEPT_NO, DEPT_NAME FROM DEPT D, EMP E WHERE D.DEPT_NO = E.DEPT_NO; EMP 테이블 FULL SCAN EXISTS 사용문장 SELECT DEPT_NO, DEPT_NAME FROM DEPT D WHERE EXISTS (SELECT 'X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); EMP 테이블 INDEX SCAN

SQL의 활용 5. Row수 count 하기 6. Table Alias의 사용 일반적인 믿음과 달리 COUNT(*)가 COUNT(1)보다 빠르다. 만약 인덱스를 통해 COUNT 한 값을 추출하고자 할 때에는 인덱스로 잡혀있는 컬럼을 COUNT(EMPNO)와 같이 추출하는 것이 가장 빠르게 결과값을 얻을 수 있다. 6. Table Alias의 사용 여러 개의 테이블에 대한 Query시 항상 테이블에 대한 alias를 사용하고, 각각의 컬럼에 alias를 붙여 사용하는 것이 좋다. ORACLE이 dictionary에서 해당 컬럼이 어느 테이블에 있는지를 찾지 않아도 되므로 parsing 시간을 줄일 수 있고, 컬럼에 대한 혼동을 미연에 방지 할 수 있다.

SQL의 활용 7. WHERE절과 HAVING절의 차이 자주 사용하지는 않지만 간혹 HAVING을 WHERE 대신 사용하는 경우가 있다. 그러나 SELECT문에서 HAVING을 WHERE 대신 사용하는 것은 피하는 것이 좋다. HAVING은 fetch된 row들에 대한 filter 역할을 한다. 여기에는 sort나 sum 등의 작업이 수반된다. 만약 select 하고자 하는 데이터를 일정 조건에 따라 추출하고자 할 경우에는 where절을 사용하여 HAVING을 사용함으로써 발생할 수 있는 overhead를 줄여주는 것이 좋다. HAVING절 사용문장 SELECT JOB, AVG(SAL) FROM EMP GROUP BY JOB HAVING JOB = ‘PRESIDENT’ OR JOB = ‘MANAGER’; GROUP BY 이후 결과를 FILTER 함 WHERE절 사용문장 SELECT JOB, AVG(SAL) FROM EMP WHERE JOB = ‘PRESIDENT’ OR JOB = ‘MANAGER’ GROUP BY JOB; GROUP BY 전 데이터 ACCESS 단계에서 조건에서 FILER 함

SQL의 활용 8. SELECT절에서 Asterisk('*') 사용 9. UNION-ALL의 사용 Dynamic SQL 컬럼 '*'는 테이블의 모든 컬럼을 참조할 수 있게 해 준다. 그러나 이러한 '*'는 값을 되돌려 줄 때 테이블의 모든 컬럼을 변환하여 반환하므로 매우 비효율적이다. SQL Parser는 Data Dictionary에서 해당 테이블에 대한 모든 컬럼의 이름을 읽어서 SQL 명령문 내의 '*'을 대체하는 작업을 한다.비록 0.01초 밖에 더 걸리지 않는 작업일 지라도 여러 번 반복하면 많은 시간이 걸릴 수도 있으므로 되도록 Asterisk(*)를 사용하지 않는 것이 좋다. 9. UNION-ALL의 사용 두개의 query에 대해서 UNION을 사용할 때, 각각의 query에 의한 결과값이 UNION-ALL에 의해 합쳐지고 다시 내부 작업인 SORT UNIQUE 작업에 의해 최종 결과값을 사용자에게 되돌려 준다. 이 때 UNION 대신 UNION-ALL을 사용하게 되면 SORT UNIQUE 작업은 불필요하게 되며, 그만큼의 시간을 줄일 수 있고 수행 성능을 향상시킬 수 있다. 이는 SORT가 필요하지 않은 경우에만 가능하므로 정확히 확인하고 사용하여야 한다.

SQL의 활용 10. ORDER BY를 사용하지 않고 정렬하기 ORDER BY을 사용할 때 인덱스를 사용하여 sort를 하지 않고 정렬된 결과값을 얻고자 할 때에는 다음의 두 조건을 만족하여야 한다. ▶ ORDER BY에 사용된 모든 컬럼이 동일한 순서로 하나의 인덱스로 만들어져 있어야 한다. ▶ ORDER BY에 사용된 모든 컬럼은 테이블 정의에 반드시 NOT NULL이어야 한다. (Null값은 인덱스에 저장되지 않으므로) Case 2에서처럼 의미 없는 Where에 의해 ORDER BY와 같이 sort 과정을 거치지 않고도 동일한 결과를 얻을 수 있다.

SQL의 활용 11. WHERE절에서 인덱스 사용을 위한 주의할 사항

SQL의 활용 12. DECODE 함수를 통한 내부처리 단축 ( DB CALL 줄이기 ) DECODE 함수를 활용하여 동일한 row에 대해 다시 읽는 것을 방지하거나 동일한 테이블에 대한 join을 피할 수 있다. 비슷한 문장을 두번 나누어 처리 SELECT COUNT(*), SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 AND ENAME LIKE 'SMITH%'; WHERE DEPT_NO = 0030 SELECT COUNT(DECODE(DEPT_NO, 0020, 1, NULL)) D20_CNT, SUM (DECODE(DEPT_NO, 0020, SAL, NULL)) D20_SAL, COUNT(DECODE(DEPT_NO, 0030, 1, NULL)) D30_CNT, SUM (DECODE(DEPT_NO, 0030, SAL, NULL)) D30_SAL FROM EMP WHERE ENAME LIKE 'SMITH%'; DECODE 문으로 문장 통합

SQL의 활용 13. 1 QUERY 시 테이블에 대한 참조를 최소화 ( WHERE 조건 ) Query시 테이블에 대한 access 회수를 최소화 함으로써 성능을 향상 시킬 수 있다. 특히 Sub-query를 포함하거나 여러 컬럼에 대한 update를 수행할 때 작업 시간을 단축할 수 있다. 동일 테이블 두번참조 ( 비효율 ) SELECT TAB_NAME FROM TABLES WHERE TAB_NAME = (SELECT TAB_NAME FROM TAB_COLUMNS WHERE VERSION = 604) AND DB_VER = (SELECT DB_VER WHERE VERSION = 604); SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME, DB_VER) = (SELECT TAB_NAME, DB_VER FROM TAB_COLUMNS WHERE VERSION = 604); 테이블을 한번만 참조하도록 ( 효율적 )

SQL의 활용 13.2 QUERY 시 테이블에 대한 참조를 최소화 (MULTI COLUMN UPDATE ) 동일 테이블 두번참조 ( 비효율 ) UPDATE EMP SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES), SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES ) WHERE EMP_DEPT = 0020; UPDATE EMP SET (EMP_CAT, SAL_RANGE) = (SELECT MAX(CATEGORY), MAX(SAL_RANGE) FROM EMP_CATEGORIES) WHERE EMP_DEPT = 0020; 테이블을 한번만 참조하도록 ( 효율적 )

SQL의 활용 14. Stored Function을 활용한 SQL의 부하 감소 JOIN 수행후 GROUP BY 시 부하가 클 경우 부하를 감소 시킨 사례 JOIN 후 GROUP BY 수행한 경우 SELECT H.EMPNO, E.ENAME, T.TYPE_DESC, COUNT(*) FROM HISTORY_TYPE T, EMP E WHERE H.EMPNO = E.EMPNO GROUP BY H.EMPNO, E.ENAME, T.TYPE_DESC; CREATE OR REPLACE FUNCTION Lookup_Emp (emp IN NUMBER) RETURN VARCHAR2 AS ename VARCHAR2(30); CURSOR C1 IS SELECT ENAME FROM EMP WHERE EMPNO = emp; BEGIN OPEN C1; FETCH C1 INTO ename; CLOSE C1; RETURN (NVL(ename, '?'); END; JOIN 후 GROUP BY 수행시 JOIN ,GROUP BY 수행에 부하 유발 GROUP BY 수행후 STORED FUNCTION 호출 SELECT H.EMPNO, Lookup_Emp(H.EMPNO), H.HIST_TYPE, COUNT(*) FROM EMP_HISTORY H GROUP BY H.EMPNO, H.HIST_TYPE; GROUP BY 만 수행후 최종 SELECT 절에서 FUNCTION 호출

MAX, MIN 사용 시 인덱스와 ROWNUM을 최대한 활용하라. Case 별 사례 MAX, MIN 사용 시 인덱스와 ROWNUM을 최대한 활용하라. Select max(sal) from employee ● S O R T TABLE Select /*+index_desc(e I_sal ) */ sal from employee e where sal > 0 and ROWNUM =1; INDEX(SAL)

Case 별 사례 1:M select a.rmp into :b0 from mrdrm a where a.c_cd='003' and a.cno=:b1 and a.shcd=:b2 and a.dt= ( select max(b.dt) from mrdrm b where b.c_cd=a.c_cd and b.cno= a.cno and b.shcd=a.shcd and b.dt<=:b3) EXECUTION PLAN -------------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'MRDRM' 2 1 INDEX (RANGE SCAN) OF 'MRDRM_IDX02' (UNIQUE) 3 2 SORT (AGGREGATE) 4 3 INDEX (RANGE SCAN) OF 'MRDRM_IDX02' (UNIQUE) 인덱스 정보 ---------------------------------------------------- MRDRM_IDX02 : C_CD+CNO+SHCD+DT MRDRM_IDX02 'MRDRM_IDX02' MRDRM SORT후 MAX(DT)와 비교 1:M

Case 별 사례 1:1 select a.rmp into :b0 from mrdrm a where a.c_cd='003' EXECUTION PLAN ------------------------------------------------------------------------ 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'MRDRM' 2 1 INDEX (RANGE SCAN) OF 'MRDRM_IDX02' (UNIQUE) 3 2 COUNT (STOPKEY) 4 3 INDEX (RANGE SCAN DESCENDING) OF 'MRDRM_IDX02' 인덱스 정보 ---------------------------------------------------- MRDRM_IDX02 : C_CD+CNO+SHCD+DT select a.rmp into :b0 from mrdrm a where a.c_cd='003' and a.cno=:b1 and a.shcd=:b2 and a.dt= ( select /*+index_desc (b mrdrm_idx02)*/ b.dt from mrdrm b where b.c_cd=a.c_cd and b.cno= a.cno and b.shcd=a.shcd and b.dt<=:b3 and ROWNUM=1) 역순으로 첫번째 DT와 비교 1:1 'MRDRM_IDX02' MRDRM

Case 별 사례 SELECT 'OUT' IN_OUT, 'OWP' CLSS, nvl(B.ITM_TYP_CD,' ') ITM_TYP_CD, nvl(B.TRD_TR_DVCD,' ') TRD_TR_DVCD FROM ITEM B WHERE B.C_CD = :C_Cd AND B.ORDDAY = DECODE(B.ORD_SVCD,'02',:svcDay,:WorkDay) AND B.ITM_TYP_CD = '01’ AND B.ORD_SVCD IN ('01','02','04') EXECUTION PLAN --------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 PARTITION (CONCATENATED) 2 1 TABLE ACCESS (FULL) OF ‘ITEM'

Case 별 사례 SELECT 'OUT' IN_OUT, 'OWP' CLSS, nvl(B.ITM_TYP_CD,' ') ITM_TYP_CD, nvl(B.TRD_TR_DVCD,' ') TRD_TR_DVCD FROM ITEM B WHERE B.C_CD = :C_Cd ((B.ORDDAY = :TrDay AND B.ORD_DVCD='02’) OR (B.ORDDAY = :WorkDay AND B.ORD_DVCD<>'02’)) AND B.ITM_TYP_CD = '01’ AND B.ORD_SVCD IN ('01','02','04') EXECUTION PLAN ------------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 CONCATENATION 2 1 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF ‘ITEM' 3 2 INDEX (RANGE SCAN) OF 'PK_ITEM_IND01' (UNIQUE) 4 1 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF ‘ITEM' 5 4 INDEX (RANGE SCAN) OF 'PK_ITEM_IND01' (UNIQUE)

Case 별 사례 SELECT A.C_CD,SUBSTR(A.AC_NO,10,2), sum(decode(B.AC_STUS_CD,'04',A.gen_de,0)) FROM ACCOUNT B, CUSTOMER A WHERE A.c_cd = :c_cd AND A.PD_CD LIKE :IN_pd_cd AND A.PD_CD <> '03' AND A.GEN > 0 AND A.C_CD = B.C_CD AND A.AC_NO = B.AC_NO AND B.AC_TYP_CD <> '06’ AND SUBSTR(A.AC_NO,1,3) = :IN_org_cd AND SUBSTR(A.AC_NO,4,6) < '600000’ GROUP BY A.C_CD,SUBSTR(A.AC_NO,10,2),SUBSTR(A.AC_NO,1,3) EXECUTION PLAN ---------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (GROUP BY) 2 1 PARTITION (CONCATENATED) 3 2 NESTED LOOPS 4 3 TABLE ACCESS (FULL) OF ‘CUSTOMER' 5 3 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'ACCOUNT' 6 5 INDEX (UNIQUE SCAN) OF 'PK_ACCCOUNT_01' (UNIQUE)

Case 별 사례 SELECT A.C_CD, …… FROM ACCOUNT B,CUSTOMER A WHERE A.c_cd = :c_cd AND A.PD_CD LIKE :IN_pd_cd AND A.PD_CD <> '03' AND A.GEN > 0 AND A.C_CD = B.C_CD AND A.AC_NO = B.AC_NO AND B.AC_TYP_CD <> '06' AND A.AC_NO between :IN_org_cd||'00000000’ and :IN_org_cd||'59999999' GROUP BY A.C_CD,SUBSTR(A.AC_NO,10,2), SUBSTR(A.AC_NO,1,3) EXECUTION PLAN ---------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (GROUP BY) 2 1 NESTED LOOPS 3 2 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF ‘CUSTOMER' 4 3 INDEX (RANGE SCAN) OF 'PK_CUSTOMER' (UNIQUE) 5 2 PARTITION (SINGLE) 6 5 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'ACCOUNT' 7 6 INDEX (UNIQUE SCAN) OF 'PK_ACCCOUNT_01' (UNIQUE)