36
1 Oracle Data Access Pattern Oracle Data Access Pattern () 오픈메이드 컨설팅 오동 동규 규 수석 수석 수석 수석 컨설턴트 컨설턴트 컨설턴트 컨설턴트 Special Key Note Special Key Note

Oracle Data Access Pattern - jigi.net · 3 Why is The Pattern Important? >SQL 의 성능을의 성능을 좌지 우지 함. >SQL 성능이슈의 1/3 이 Data Access Pattern 이이

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

  • 1

    Oracle Data Access PatternOracle Data Access Pattern

    � (주) 오픈메이드 컨설팅

    � 오오오오 동동동동 규규규규 수석수석수석수석 컨설턴트컨설턴트컨설턴트컨설턴트

    Special Key NoteSpecial Key Note

  • 2

    What is Data Access Pattern?

    >데이터를데이터를데이터를데이터를 I/O 하는하는하는하는 방식방식방식방식

    • Index Scan

    • Full Table Scan

    •Rowid

  • 3

    Why is The Pattern Important?

    >SQL 의의의의 성능을성능을성능을성능을 좌지좌지좌지좌지 우지우지우지우지 함함함함.

    >SQL 성능이슈의성능이슈의성능이슈의성능이슈의 1/3 이이이이 Data Access Pattern 이이이이 잘못되어잘못되어잘못되어잘못되어 발생발생발생발생

    >모든모든모든모든 DBMS 의의의의 Data Access Pattern이이이이 유사함유사함유사함유사함.

    • Index Scan

    • Full Table Scan

    • Rowid

    • 3가지가지가지가지 용도를용도를용도를용도를 알아야알아야알아야알아야 한다한다한다한다.

  • 4

    How do You learn Data Access Pattern?

    Only Book?

    Probably Not!

    Then How?

  • 5

    • Rowid

    • Index Unique Scan

    • Index Range Scan

    • Index Inlist Iterator

    • Index Skip Scan

    • Index Full Scan

    • Index Fast Full Scan

    • Bit Map Index Combination

    • Full Table Scan

    Oracle Data Access PatternOracle Data Access Pattern--목차목차목차목차목차목차목차목차

    Index 사용

    Here it is

    EveryThing About Oracle Data Access Pattern

  • 6

    Index Fast Full Scan 은 예외적으로Full Table Scan 처럼 Multi Block I/O 를사용함

    • Rowid

    • Index Unique Scan

    • Index Range Scan

    • Index Range Scan Descending

    • Index Range Scan (min/max)

    • Index Inlist Iterator

    • Index Inlist Iterator Descending

    • Index Skip Scan

    • Index Skip Scan Descending

    • Index Full Scan

    • Index Full Scan Descending

    • Index Full Scan (min/max)

    • Index Fast Full Scan

    • BIT MAP OR

    • BIT MAP AND

    • BIT MAP MINUS

    • BIT MAP MERGE

    • Full Table Scan

    Oracle Data Access PatternOracle Data Access Pattern--상세목차상세목차상세목차상세목차상세목차상세목차상세목차상세목차

    Bit Map Index Combination 의 4가지 Pattern

  • 7

    RowidRowid

    > 발생조건발생조건발생조건발생조건• Rowid가 조건으로 공급된 경우

    • 인덱스를 사용하여 Table 을 access 한경우

    > 특징특징특징특징• Rowid를 이용해서 해당테이블의 특정 Block의 특정 Row를 찾아간다.

    • 가장 빠른 Access 방식이다.

    > 적용• max /min 일자를 찾아서 그일자에 해당하는 값을 select 할때

    • 주로 self join 시 사용

    > HintHintHintHint• /*+ rowid(테이블명 또는 테이블별칭) */

  • 8

    RowidRowid--예제예제예제예제예제예제예제예제((인라인뷰인라인뷰인라인뷰인라인뷰인라인뷰인라인뷰인라인뷰인라인뷰 사용사용사용사용사용사용사용사용))

    > 실행계획실행계획실행계획실행계획• 요구사항: 부서별로 가장 최근에 입사한 사원정보를 한명씩 출력하시오.

    select b.empno, b.ename, b.deptno, b.job, b.hiredate

    from (select substr(max(to_char(hiredate,'YYYYMMDD')||ROWID), 9) as rid

    from emp

    group by deptno) a,

    emp b

    where b.rowid = a.rid

    ---------------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Reads | Used-Mem |

    ---------------------------------------------------------------------------------------------------------

    | 1 | NESTED LOOPS | | 1 | 3 |00:00:00.01 | 10 | 2 | |

    | 2 | VIEW | | 1 | 3 |00:00:00.01 | 7 | 2 | |

    | 3 | HASH GROUP BY | | 1 | 3 |00:00:00.01 | 7 | 2 | 578K (0)|

    | 4 | TABLE ACCESS FULL | EMP | 1 | 14 |00:00:00.01 | 7 | 2 | |

    | 5 | TABLE ACCESS BY USER ROWID| EMP | 3 | 3 |00:00:00.01 | 3 | 0 | |

    ---------------------------------------------------------------------------------------------------------

  • 9

    RowidRowid--예제예제예제예제예제예제예제예제((서브쿼리사용서브쿼리사용서브쿼리사용서브쿼리사용서브쿼리사용서브쿼리사용서브쿼리사용서브쿼리사용))

    > 실행계획실행계획실행계획실행계획

    • 요구사항: 부서별로 가장 최근에 입사한 사원정보를 한명씩 출력하시오.

    select b.empno, b.ename, b.deptno, b.job, b.hiredatefrom emp bwhere b.rowid in ( select substr(max(to_char(hiredate,'YYYYMMDD')||ROWID), 9)

    from empgroup by deptno)

    -------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Reads | Used-Mem |-------------------------------------------------------------------------------------------------------------| 1 | NESTED LOOPS | | 1 | 3 |00:00:00.01 | 10 | 6 | || 2 | VIEW | VW_NSO_1 | 1 | 3 |00:00:00.01 | 7 | 6 | || 3 | HASH UNIQUE | | 1 | 3 |00:00:00.01 | 7 | 6 | 597K (0)|| 4 | HASH GROUP BY | | 1 | 3 |00:00:00.01 | 7 | 6 | 592K (0)|| 5 | TABLE ACCESS FULL | EMP | 1 | 14 |00:00:00.01 | 7 | 6 | || 6 | TABLE ACCESS BY USER ROWID| EMP | 3 | 3 |00:00:00.01 | 3 | 0 | |-------------------------------------------------------------------------------------------------------------

  • 10

    Index Unique ScanIndex Unique Scan

    > 발생조건발생조건발생조건발생조건• Unique 인덱스및 PK 인덱스의 모든컬럼에 대하여 Where 절에 = 조건으로상수및 변수가 들어올때 발생됨.

    > 특징특징특징특징• 해당조건을 만족하는 하나의 row 만 Scan 한다.

    • 빠른성능

    > 적용• OLTP 시스템

    • 건단위로 처리해야 하는경우

    > HintHintHintHint• /*+ index(테이블명 또는 테이블별칭 인덱스명) */

    select /*+ index(emp pk_emp) */ empno, ename

    from emp

    where empno = 7782 ;

  • 11

    Index Unique ScanIndex Unique Scan--예제예제예제예제예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select empno, ename

    from emp

    where empno = 7782 ;

    ------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |

    ------------------------------------------------------------------------------------------------

    | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 1 | 1 |00:00:00.01 | 2 |

    |* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | 1 | 1 |00:00:00.01 | 1 |

    ------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    2 - access("EMPNO"=7782)

    7782

    EMPNO 인덱스인덱스인덱스인덱스 EMP 테이블테이블테이블테이블7782 CLARK MANAGER ….

  • 12

    Index Index RangeRange ScanScan

    > 발생조건발생조건발생조건발생조건• Non-Unique Index를 Access하는 경우

    • Unique Index를 구성하고 있는 컬럼 중 일부 컬럼에만 값이 공급된 경우

    • Unique Index에 Range 조건(like, between, >, =, 특징• 해당 조건을 만족하는 범위 + 아닌 값 하나(1PlusScan)를 읽게 된다.

    • Range 조건이 들어온 경우 Index구성 순서상 이후에 있는 컬럼에 공급된조건들은 작업범위를 줄이는데 작용하지 못한다.

    예외상황:9i 이후부터 index skip scan

    • 수행속도가 Range 에 의해서 좌우된다.

    > 적용• 10만건 이하의 건수를 access 할때

    • 10만건 이상이라도 부분범위처리가 가능할때

    • 10만건 이상이라도 인덱스만 scan 하고 table access 가 없을때

    • 주로 OLTP

    > HintHintHintHint• /*+ index(테이블명 또는 테이블별칭 인덱스명) */

    • /*+ index_desc(테이블명 또는 테이블별칭 인덱스명) */

  • 13

    Index Index RangeRange ScanScan--예제예제예제예제예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select empno, ename, mgr from empwhere empno BETWEEN 7782 AND 7839;

    ------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 3 | 3 |00:00:00.01 | 5 ||* 2 | INDEX RANGE SCAN | PK_EMP | 1 | 3 | 3 |00:00:00.01 | 2 |------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    2 - access("EMPNO">=7782 AND "EMPNO"

  • 14

    Index Index RangeRange ScanScan Descending --예제예제예제예제예제예제예제예제

    >실행계획실행계획실행계획실행계획

    select empno, ename, mgr

    from emp

    where empno BETWEEN 7782 AND 7839

    order by empno desc

    ----------------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |

    ----------------------------------------------------------------------------------------------------------

    | 1 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 3 | 3 |00:00:00.01 | 5 | 3 |

    |* 2 | INDEX RANGE SCAN DESCENDING| PK_EMP | 1 | 3 | 3 |00:00:00.01 | 2 | 1 |

    ----------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    2 - access("EMPNO"=7782)

    7782

    EMPNO 인덱스인덱스인덱스인덱스 EMP 테이블테이블테이블테이블7782 CLARK 7839 ….

    7788

    7839

    7698

    7788 SCOTT 7566 ….

    7839 KING NULL ….

  • 15

    Index Index RangeRange ScanScan (min/max)(min/max)--예제예제예제예제예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select max(empno)

    from emp

    where empno between 7782 and 7839

    ----------------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |

    ----------------------------------------------------------------------------------------------------------

    | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 1 | 1 |

    | 2 | FIRST ROW | | 1 | 2 | 1 |00:00:00.01 | 1 | 1 |

    |* 3 | INDEX RANGE SCAN (MIN/MAX)| PK_EMP | 1 | 2 | 1 |00:00:00.01 | 1 | 1 |

    ----------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    3 - access("EMPNO">7839)

    7782

    7788

    7839

    EMPNO 인덱스인덱스인덱스인덱스

  • 16

    Index Index InlistInlist IteratorIterator

    > Iteration Iteration Iteration Iteration • 의미 : 같은 일을 반복함

    > 발생조건발생조건발생조건발생조건• OR 조건이나 IN 조건에 상수(변수)가 들어오면 발생함

    > 특징• Concatenation 과 비슷하나 Union 으로 풀리지 않고 반복수행된다.• 값이 상수나 변수로 공급될때만 발생한다.• 수행속도가 반복횟수에 의해서 좌우된다.• Iteration 에 의해 Index range scan 및 index unique scan 이 발생됨

    > 적용• Concatenation과 동일하나 Inlist Iterator 가 유리함.• Index Range Scan 이 더 유리한 경우가 있으므로 무조건 적용하지말것.• OLTP 에 적용하고 대용량배치 SQL 에서는 피한다.

    > HintHintHintHint• /*+ NUM_INDEX_KEYS(테이블명 인덱스명 컬럼개수) */ • Oracle 10.2.0.2 부터 사용가능• 인덱스 Layout: EMP_JOB_MGR_SAL_IDX (JOB_ID, MANAGER_ID, SALARY)

    SELECT /*+ NUM_INDEX_KEYS(a EMP_JOB_MGR_SAL_IDX 2) */a.*

    FROM hr.employees aWHERE job_id = :v_jobAND manager_id IN (:v_manager1, :v_manager2)

    • 인덱스의 2번째 컬럼까지 Inlist Iterator 로 scan 하라는 의미

  • 17

    Index Inlist Iterator-예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select empno, ename, mgr

    from emp

    where empno in (7782, 7839);

    혹은혹은혹은혹은

    select empno, ename, mgr

    from emp

    where (empno = 7782 or empno = 7839);

    -------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |

    -------------------------------------------------------------------------------------------------

    | 1 | INLIST ITERATOR | | 1 | | 2 |00:00:00.01 | 4 |

    | 2 | TABLE ACCESS BY INDEX ROWID| EMP | 2 | 2 | 2 |00:00:00.01 | 4 |

    |* 3 | INDEX UNIQUE SCAN | PK_EMP | 2 | 2 | 2 |00:00:00.01 | 2 |

    -------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    3 - access(("EMPNO"=7499 OR "EMPNO"=7839))

    7782

    EMPNO 인덱스인덱스인덱스인덱스 EMP 테이블테이블테이블테이블7782 CLARK 7839 ….

    7839

    7839 KING NULL ….

    ①①①①

    ②②②②

  • 18

    Index Inlist Iterator Descending-예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select empno, ename, mgr

    from emp

    where empno in (7839, 7782)

    order by empno desc;

    혹은혹은혹은혹은

    select empno, ename, mgr

    from emp

    where (empno = 7839 or empno = 7782)

    order by empno desc;

    -----------------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |

    -----------------------------------------------------------------------------------------------------------

    | 1 | INLIST ITERATOR | | 1 | | 2 |00:00:00.01 | 5 | 2 |

    | 2 | TABLE ACCESS BY INDEX ROWID | EMP | 2 | 2 | 2 |00:00:00.01 | 5 | 2 |

    |* 3 | INDEX RANGE SCAN DESCENDING| PK_EMP | 2 | 2 | 2 |00:00:00.01 | 3 | 1 |

    -----------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    3 - access(("EMPNO"=7499 OR "EMPNO"=7839))

    7782

    EMPNO 인덱스인덱스인덱스인덱스 EMP 테이블테이블테이블테이블7782 CLARK 7839 ….

    7839

    7839 KING NULL ….

    ①①①①

    ②②②②

  • 19

    Index Skip ScanIndex Skip Scan

    > 발생조건발생조건발생조건발생조건• 결합인덱스시 처음이나 중간의 조건이 빠졌을경우

    • 9i 이전 까지는 결합 인덱스에서 첫 번째 컬럼이 사용되지 않으면 인덱스의두번째 컬럼부터는 인덱스 스캔이 불가능 하였다.

    • 9i부터 Index Skip Scan으로 빠진 조건을 제외한 나머지 조건을 scan 하는것이

    가능해짐.

    > 특징• 기본적으로 index range scan 과 특징이 유사함

    • 인덱스가 col1 + col2 + col3 로 되어있을때 col1 컬럼 조건이

    where 조건에서 빠진경우에 col2 + col3 인덱스를 만든것과 비슷한 효과를

    낼수 있음.

    • 위와 비슷하게 col2 컬럼 조건이 where 조건에서 빠진경우에도 col1 + col3 인덱스를 만든것과 비슷한 효과를 낼수 있음.

    > 적용• 주로 좁은범위를 scan 할때

    • Skip 되는 컬럼의 값의 종류가 많지 않을때

    > HintHintHintHint• /*+ index_ss(테이블명 또는 테이블별칭 인덱스명) */

  • 20

    Index Skip ScanIndex Skip Scan -예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스인덱스인덱스인덱스 Lay out : mgr + job + deptno

    select /*+ index_ss(emp IX_EMP_N1) */empno, ename, mgr

    from empwhere job = 'CLERK'and deptno between 10 and 20

    ---------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |---------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 1 | 4 |00:00:00.01 | 6 ||* 2 | INDEX SKIP SCAN | IX_EMP_N1 | 1 | 4 | 4 |00:00:00.01 | 2 |---------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    2 - access("JOB"='CLERK' AND "DEPTNO">=10 AND "DEPTNO"=10 AND "DEPTNO"

  • 21

    Index Skip ScanIndex Skip Scan Descending-예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스인덱스인덱스인덱스 Lay out : mgr + job + deptno

    select /*+ index_ss_desc(emp IX_EMP_N1) */

    empno, ename, mgr

    from emp

    where job = 'CLERK'

    and deptno between 10 and 30

    order by mgr desc, job desc, deptno desc

    ------------------------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |

    ------------------------------------------------------------------------------------------------------------

    | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 1 | 4 |00:00:00.01 | 5 | 3 |

    |* 2 | INDEX SKIP SCAN DESCENDING| IX_EMP_N1 | 1 | 4 | 4 |00:00:00.01 | 2 | 1 |

    ------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):

    ---------------------------------------------------

    2 - access("JOB"='CLERK' AND "DEPTNO">=10 AND "DEPTNO"=10 AND "DEPTNO"

  • 22

    Index FullIndex Full ScanScan

    > 특징• 해당 인덱스의 모든 Block을 한번에 한 Block씩 순차적으로 읽어내려간다.(Single Block I/O)

    > 적용• 데이터가가 적고 전체건에 대하여 인덱스 컬럼으로 sort 해야하는 경우

    • min/max 를 구할경우

    • Scan 해야할 데이터가 가 많은 경우는 부분범위처리가 가능하고 인덱스 컬럼으로sort 를 해야 하는 경우만 적용할것.

    > HintHintHintHint• /*+ index(테이블명 또는 테이블별칭 인덱스명) */

    • 직접적으로 full scan 을 유도하는 힌트는 없음.

  • 23

    Index FullIndex Full ScanScan -예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select empno

    from emp

    order by empno

    ------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------ | 1 | INDEX FULL SCAN| PK_EMP | 1 | 1 | 14 |00:00:00.01 | 2 | ------------------------------------------------------------------------------------

    ①①①①

    EMPNO 인덱스인덱스인덱스인덱스②②②②

    ③③③③

  • 24

    Index FullIndex Full ScanScan Descending -예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스를 거꾸로 Scan 함

    select empno

    from emp

    order by empno desc

    -----------------------------------------------------------------------------------------------

    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |

    -----------------------------------------------------------------------------------------------

    | 1 | INDEX FULL SCAN DESCENDING| PK_EMP | 1 | 14 | 14 |00:00:00.01 | 2 |

    -----------------------------------------------------------------------------------------------

    ①①①①

    EMPNO 인덱스인덱스인덱스인덱스②②②②

    ③③③③

  • 25

    Index FullIndex Full ScanScan (min/max)-예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select max(empno) from emp

    --------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |--------------------------------------------------------------------------------------------------------| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 1 | 1 || 2 | INDEX FULL SCAN (MIN/MAX)| PK_EMP | 1 | 14 | 1 |00:00:00.01 | 1 | 1 |--------------------------------------------------------------------------------------------------------

    • 아래의 SQL 을 수행한 효과와 같음

    select /*+ index_desc(emp pk_emp) */empno

    from empWHERE empno > 0 and rownum = 1

    ①①①①

    EMPNO 인덱스인덱스인덱스인덱스

    ②②②② 7934

  • 26

    Index Fast FullIndex Fast Full ScanScan

    > 발생조건발생조건발생조건발생조건• Where절이나 Select절에 사용된 컬럼이 모두 하나의 인덱스에 구성된 컬럼인

    경우

    • 결합Index의 경우 최소한 한 Column이 NOT Null로 지정되어 있거나 where 절에 명시적으로 not null 조건을 부여해야 한다.

    > 특징• 한번에 DB_FILE_MULTIBLOCK_READ_COUNT에서 정한 크기씩 끝까지 읽어내려가며 결과 값의 Sort가 보장되지 않는다.(Multi Block I/O)

    • Full Table Scan보다 읽어야 할 Block의 수가 적어 항상 유리하다.

    > 적용• 넓은 범위검색

    • 주로 배치쿼리나 OLAP 에서 사용됨

    > HintHintHintHint• /*+ index_ffs(테이블명 또는 테이블별칭 인덱스명) */

  • 27

    Index Fast FullIndex Fast Full ScanScan -예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select /*+ index_ffs(emp pk_emp) */

    empno

    from emp

    -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |

    -------------------------------------------------------------------------------------------------- | 1 | INDEX FAST FULL SCAN| PK_EMP | 1 | 1 | 14 |00:00:00.01 | 4 | 2 | --------------------------------------------------------------------------------------------------

    EMPNO 인덱스인덱스인덱스인덱스②②②②

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    ③③③③

    ①①①①

    Multi-Block I/O

    Multi-Block I/O

  • 28

    Bit Map Index Combination

    > 발생조건발생조건발생조건발생조건• Bit Map 인덱스가 한테이블에 2개 이상일때 where 조건에두인덱스에 해당하는 컬럼의 조건을 where 절에서 모두 사용할때 발생함.

    • 9.2 미만 버젼에서는 Index Merge Plan 이 발생함.

    • 반드시 Bit Map 인덱스가 아니라도 Index Combination 이 발생할수 있음.이경우에는 Bit Map Conversion 이 추가로 발생함.

    > 특징• 첫번째 인덱스의 와 두번째 인덱스의를 이용하여 두집합간에

    AND, OR, MINUS, MERGE 연산을 하여 데이터를 엑세스한다.

    > 적용• 주로 DW 나 대용량 배치인경우 적용

    • OLTP 인 경우는 두개의 인덱스 조건이 모두 똑똑한 경우 적용가능.

    • 하지만 하나의 조건만으로 filter 되어 나오는 결과건수와 두개의 조건으로 filter 되는 나오는 결과건수가 비슷하다면 비효율이 발생함으로 무조건 적용해서는

    안됨.

    > HintHintHintHint• /*+ INDEX_COMBINE(테이블명 또는 테이블별칭 인덱스1, 인덱스2) */

  • 29

    Bit Map Index Combination --예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스 LayOut : IX_EMP_N2 : mgr

    IX_EMP_N3 : deptno

    select /*+ index_combine(emp IX_EMP_N2 IX_EMP_IDX3) */empno, ename

    from empwhere mgr = 7839 or deptno = 10

    -----------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |-----------------------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 2 | 5 |00:00:00.01 | 4 | 2 || 2 | BITMAP CONVERSION TO ROWIDS | | 1 | | 5 |00:00:00.01 | 2 | 1 || 3 | BITMAP OROROROR | | 1 | | 1 |00:00:00.01 | 2 | 1 || 4 | BITMAP CONVERSION FROM ROWIDS| | 1 | | 1 |00:00:00.01 | 1 | 0 ||* 5 | INDEX RANGE SCAN | IX_EMP_N3 | 1 | | 3 |00:00:00.01 | 1 | 0 || 6 | BITMAP CONVERSION FROM ROWIDS| | 1 | | 1 |00:00:00.01 | 1 | 1 ||* 7 | INDEX RANGE SCAN | IX_EMP_N2 | 1 | | 3 |00:00:00.01 | 1 | 1 |-----------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    5 - access("DEPTNO"=10)7 - access("MGR"=7839)

    Bit Map Or

  • 30

    Bit Map Index Combination --예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스 LayOut : IX_EMP_N2 : mgr

    IX_EMP_N3 : deptno

    select /*+ index_combine(emp IX_EMP_N2 IX_EMP_IDX3) */empno, ename

    from empwhere mgr = 7839 and deptno = 10

    -----------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |-----------------------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 1 | 1 |00:00:00.01 | 3 | 2 || 2 | BITMAP CONVERSION TO ROWIDS | | 1 | | 1 |00:00:00.01 | 2 | 1 || 3 | BITMAP ANDANDANDAND | | 1 | | 1 |00:00:00.01 | 2 | 1 || 4 | BITMAP CONVERSION FROM ROWIDS| | 1 | | 1 |00:00:00.01 | 1 | 0 ||* 5 | INDEX RANGE SCAN | IX_EMP_N3 | 1 | | 3 |00:00:00.01 | 1 | 0 || 6 | BITMAP CONVERSION FROM ROWIDS| | 1 | | 1 |00:00:00.01 | 1 | 1 ||* 7 | INDEX RANGE SCAN | IX_EMP_N2 | 1 | | 3 |00:00:00.01 | 1 | 1 |-----------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    5 - access("DEPTNO"=10)7 - access("MGR"=7839)

    Bit Map And

  • 31

    Bit Map Index Combination --예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스 drop 후 bit map index 생성create bitmap index IX_EMP_N2 on emp (mgr);create bitmap index IX_EMP_N3 on emp (deptno);

    select /*+ index_combine(emp IX_EMP_N2 IX_EMP_IDX3) */empno, mgr, deptno

    from empwhere mgr > 7600 and deptno > 20

    ------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Used-Mem |------------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 6 |00:00:00.01 | 4 | || 2 | BITMAP CONVERSION TO ROWIDS| | 1 | 6 |00:00:00.01 | 2 | || 3 | BITMAP AND | | 1 | 1 |00:00:00.01 | 2 | || 4 | BITMAP MERGEMERGEMERGEMERGE | | 1 | 1 |00:00:00.01 | 1 | 1024 (0)||* 5 | BITMAP INDEX RANGE SCAN | IX_EMP_N3 | 1 | 1 |00:00:00.01 | 1 | || 6 | BITMAP MERGEMERGEMERGEMERGE | | 1 | 1 |00:00:00.01 | 1 | 2048 (0)||* 7 | BITMAP INDEX RANGE SCAN | IX_EMP_N2 | 1 | 5 |00:00:00.01 | 1 | |------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    5 - access("DEPTNO">20)filter("DEPTNO">20)

    7 - access("MGR">7600)filter("MGR">7600)

    Bit Map Merge

  • 32

    Bit Map Index Combination --예제예제예제예제

    > 실행계획실행계획실행계획실행계획• 인덱스 drop 후 bit map index 생성create bitmap index IX_EMP_N2 on emp (mgr);create bitmap index IX_EMP_N3 on emp (deptno);

    select /*+ index_combine(emp IX_EMP_N2 IX_EMP_IDX3) */empno, mgr, deptno

    from empwhere NOT( mgr = 7698 )and deptno = 20

    -----------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Reads |-----------------------------------------------------------------------------------------------------| 1 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 5 |00:00:00.05 | 7 | 1 || 2 | BITMAP CONVERSION TO ROWIDS | | 1 | 5 |00:00:00.05 | 4 | 1 || 3 | BITMAP MINUSMINUSMINUSMINUS | | 1 | 1 |00:00:00.05 | 4 | 1 || 4 | BITMAP MINUSMINUSMINUSMINUS | | 1 | 1 |00:00:00.05 | 3 | 1 ||* 5 | BITMAP INDEX SINGLE VALUE| IX_EMP_N3 | 1 | 1 |00:00:00.05 | 2 | 1 ||* 6 | BITMAP INDEX SINGLE VALUE| IX_EMP_N2 | 1 | 1 |00:00:00.01 | 1 | 0 ||* 7 | BITMAP INDEX SINGLE VALUE | IX_EMP_N2 | 1 | 1 |00:00:00.01 | 1 | 0 |-----------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):---------------------------------------------------

    5 - access("DEPTNO"=20)6 - access("MGR"=7698)7 - access("MGR" IS NULL)

    Bit Map Minus

  • 33

    Full TableFull Table ScanScan

    > 발생조건발생조건발생조건발생조건• 아무런 조건 없이 Table을 읽게 한 경우

    • 인덱스가 걸려있지 않은 컬럼에 대해서 조건을주고 Table을 읽게 한 경우

    • 인덱스가 걸려있는 컬럼에 조건을 부여했을지라도 Optimizer가 Full Table

    Scan이 유리하다고 판단한 경우

    > 특징• 테이블의 첫 Row가 들어있는 Block부터 HWM(High Water Mark)까지 읽는다

    • DB_FILE_MULTIBLOCK_READ_COUNT가 16이면 한번 i/o 할때 16 block 씩scan 한다. (MultiBlock I/O)

    > 적용• 넓은 범위검색

    • 주로 배치쿼리나 OLAP 에서 사용됨

    > HintHintHintHint• /*+ full(테이블명 또는 테이블별칭 인덱스명) */

  • 34

    Full TableFull Table ScanScan-예제예제예제예제

    > 실행계획실행계획실행계획실행계획

    select /*+ full(emp) */

    empno, ename

    from emp

    ------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------ | 1 | TABLE ACCESS FULL| EMP | 1 | 1 | 14 |00:00:00.01 | 8 | ------------------------------------------------------------------------------------

    EMP 테이블테이블테이블테이블②②②②

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    Block

    ③③③③

    ①①①①

    Multi-Block I/O

    Multi-Block I/O

  • 35

    • Rowid

    • Index Unique Scan

    • Index Range Scan

    • Index Inlist Iterator

    • Index Skip Scan

    • Index Full Scan

    • Index Fast Full Scan

    • Bit Map Index Combination

    • Full Table Scan

    Oracle Data Access PatternOracle Data Access Pattern--정리정리정리정리정리정리정리정리

    Index 사용

  • 36

    Oracle Data Access PatternOracle Data Access Pattern

    감사합니다감사합니다감사합니다감사합니다감사합니다감사합니다감사합니다감사합니다. .

    Special Key NoteSpecial Key Note