SSISO Community

시소당

Data Access Pattern - ORACLE

Data Access Pattern - Index Combine

1.발생규칙
1) Bit Map 인덱스가 한테이블에 2개 이상일때 where 조건에
두인덱스에 해당하는 컬럼의 조건을 다사용할때 발생함.
2)9.2 밑의 버젼에서는 Index Merge Plan 이 발생함.
3)꼭 Bit Map 인덱스가 아니라도 Index Combine 이 발생할수 있음.
이경우에는 Bit Map Conversion 이 추가로 발생함.

2.엑세스 형태
-첫번째 인덱스의 와 두번째 인덱스의를 이용하여 두집합간에
AND, OR, MINUS, MERGE 연산을 하여 데이터를 엑세스한다.


3.적용범위
1) DW 나 대용량 배치인경우 적용
2)OLTP 인 경우는 인덱스 조건이 똑똑한경우 적용.

4.Plan 및 SQL

CREATE TABLE t1
(c1 NUMBER, c2 NUMBER);

CREATE BITMAP INDEX i1 ON t1 (c1);
CREATE BITMAP INDEX i2 ON t1 (c2);


1) BIT MAP OR
SELECT /*+ INDEX_COMBINE (t1 i1 i2) */ c1,c2
FROM t1
WHERE c1 = 0 OR c2 = 0;

SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T1‘
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP OR
4 3 BITMAP INDEX (SINGLE VALUE) OF 'I1‘
5 3 BITMAP INDEX (SINGLE VALUE) OF 'I2'


2) BIT MAP AND
SELECT /*+ INDEX_COMBINE (t1 i1 i2) */ c1,c2
FROM t1
WHERE c1 = 0 AND c2 = 0;

SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T1‘
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP INDEX (SINGLE VALUE) OF 'I1‘
5 3 BITMAP INDEX (SINGLE VALUE) OF 'I2'


3) BIT MAP MINUS
SELECT /*+ INDEX_COMBINE (t1 i1 i2) */ c1,c2
FROM t1
WHERE c1 = 0 AND NOT c2 = 0;


0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T1‘
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP MINUS
4 3 BITMAP MINUS
5 4 BITMAP INDEX (SINGLE VALUE) OF 'I1‘
6 4 BITMAP INDEX (SINGLE VALUE) OF 'I2‘ --> c2 IS NULL 에 대한 ACCESS
7 3 BITMAP INDEX (SINGLE VALUE) OF 'I2' --> c2 = 0 에 대한 ACCESS

# 위경우에 c2 IS NULL 항목이 NOT NULL 이면 6번 ACCESS 가 발생하지 않는다.


4) BIT MAP MERGE
SELECT /*+ INDEX_COMBINE (t1 i1 i2) */ c1,c2
FROM t1
WHERE c1 > 0 AND c2 = 0;


0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T1'
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP INDEX (SINGLE VALUE) OF 'I2‘
5 3 BITMAP MERGE
6 5 BITMAP INDEX (RANGE SCAN) OF 'I1'

Data Access Pattern - Inlist Iterator

1.발생규칙
-OR 조건이나 IN 조건에 상수(변수)가 들어오면 발생함

2.Access 방식
-Concatenation 과 비슷하나 Union 으로 풀리지않고 반복수행한다.
-값이 상수나 변수로 공급될때만 발생한다.

3.적용범위

-Concatenation과 동일하나 Inlist Iterator 가 유리한경우가 많음
-OLTP 에 적용하고 대용량배치 SQL 에서는 피한다.

4.Hint

-특별한 힌트는 없지만 no_expand 힌트를 쓰면 Concatenation 으로 풀리지 않고
Inlist Iterator 로 풀릴가능성이 높다.

SELECT /*+ no_expand */
empno, ename, sal

FROM emp
WHERE empno IN (7501,7502,7503) ;



SELECT STATEMENT

INLIST ITERATOR
TABLE ACCESS BY INDEX ROWID EMP
INDEX (RANGE SCAN) PK_EMP


1.발생규칙

OR조건이나 IN 상수조건이 있는경우에 걸리는 두개의 조건을 개별적으로 검색하고, 나머지 조건도 전부 적용해서 검색 한 후, 나중에 이 결과를 합치게 된다.이 내용이 플랜에는 CONCATENATION으로 표현 된다.


2.Access 방식

SELECT /*+USE_CONCAT*/ columns

FROM tables

WHERE (조건1 OR 조건2)

AND 조건3;

위처럼 조건절이 되는경우 아래처럼 실행계획이 풀린다.

SELECT columnsFROM tables

WHERE 조건1

AND 조건3

UNION ALL

SELECT columns

FROM tables

WHERE 조건2

AND 조건3;


3.적용범위

-인덱스 조건이 똑똑하여 빠른 OUTPUT 이 보장될경우(OLTP)

-ORDER BY절이 있을 경우 결과에 대한 정렬 처리가 추가로 필요하게 되므로, 결과값이 많을 경우에는 불리하게 작용할 수 있다.

-대용량 배치쿼리에서는 피한다.


4.Hint

/*+USE_CONCAT*/

5.PLAN

SELECT /*+USE_CONCAT*/ columns
FROM tables
WHERE (조건1 OR 조건2)
AND 조건3;


CONCATENATION
TABLE ACCESS (BY ROWID) OF ‘TEST_TAB1’
INDEX (RANGE SCAN) OF ‘IDX1’
TABLE ACCESS (BY ROWID) OF ‘TEST_TAB1’
INDEX (RANGE SCAN) OF ‘IDX1’


 

1.발생규칙 :

-결합인덱스시 처음이나 중간의 조건이 빠졌을경우
-결합 인덱스에서 첫 번째 컬럼이 사용되지 않으면 무조건 인덱스 스캔이 불가능 하였다. 하지만 9i부터 인덱스 스킵 스캔으로 가능해짐.


2.Access 방식

-Index Skip Scan의 원리
① 어떤 테이블의 인덱스가 sal_typ(매출유형), item_cd(상품코드), sal_dt(매출일자)로 구성되어 있다고 가정했을 경우
② 쿼리의 조건에서 item_cd와 sal_dt 만 사용 되었다.
③ sal_typ의 값이 D(내수),E(수출),L(로컬) 이렇게 세 종류만 있다고 가정을 하였을 경우. Index Skip Scan을 적용하면..
④ sal_typ IN (‘D’,’E’,’L’) 의 조건을 추가한 것과 동일한 효과를 얻을 수 있다.
- 결국 생락 된 첫 번째 컬럼의 값이 조건 절에 자동으로 추가되는 것과 유사한 효과가 난다.
- WHERE sal_typ = ‘D’ and item_cd = … UNION ALL
WHERE sal_typ = ‘E’ and item_cd = … UNION ALL
WHERE sal_typ = ‘L’ and item_cd = … → 여기서 ‘D’,’E’,’L’을 논리적 서브 인덱스라고 한다.

3.적용범위

- Index Skip Scan은 서브 인덱스의 종류가 많지 않고, 뒤에 오는 컬럼의 종류가 많을 때 가장 좋은 결과를 얻을 수 있다.

4.Hint

SELECT /*+ INDEX_SS(miod_div miod_div_idx) */ i_bugt_cd
FROM miod_div
WHERE d_io = '20010403'
AND o_io = 6
AND i_io = '20'
AND i_io_div = '6200'

5.Plan
SELECT STATEMENT CHOOSE-Cost : 4519
TABLE ACCESS BY INDEX ROWID MATS.MIOD_DIV(1)
INDEX SKIP SCAN MATS.MIOD_DIV_IDX(NU) (I_MATR,D_IO,O_IO,I_IO,I_IO_DIV)

Data Access Pattern - Rowid

1.발생규칙
•Rowid가 조건으로 공급된 경우
•인덱스를 사용하여 Table 을 access 한경우

2.Access 방식
•Rowid를 이용해서 특정 Block의 특정 Row를 찾아간다
•가장 빠른 Access 방식이다.

3.적용범위
•max /min 일자를 찾아서 그일자에 해당하는 값을 select 할때(self join 시 사용)

4.Hint

select *
from emp
where rowid = :v_rid


-------------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
TABLE ACCESS (BY [INDEX] ROWID) OF 'EMP'
 
1.발생규칙
•Optimizer가 Full Table Scan하고 Sort하는 것 보다는 Index Full Scan해 Sort작업을 따로
수행하지 않는 것이 유리하다고 판단한 경우

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

3.적용범위
•건수가 많더라도 1건만 scan 하고 끝낼수 있을경우
•부분범위처리가 가능한경우

4.주의사항
•muti-block-I/O 가 아님(한BLOCK 씩만 읽을수 있음)
INDEX FAST FULL SCAN 과 다르므로 주의한다.(배치SQL 에서는 피한다.)

5.HINT
/*+ INDEX(테이블명 인덱스명) */

select /*+ index(a emp_idx05) */
empno, ename, job, hiredate
from emp a
where job = 'SALESMAN'

-------------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
TABLE ACCESS (BY [INDEX] ROWID) OF 'EMP'
INDEX (FULL SCAN) OF 'EMP_IDX05' (NON-UNIQUE)

Data Access Pattern - INDEX RANGE SCAN

1.발생규칙
•Non-Unique Index를 Access하는 경우
•Unique Index를 구성하고 있는 컬럼 중 일부 컬럼에만 값이 공급된 경우
•Unique Index에 Range 조건(like, between, >, <, >=, <=)으로 값이 공급되는 경우

2.Access 방식
•해당 조건을 만족하는 범위 + 아닌 값 하나(1PlusScan)를 읽게 된다.
•Range 조건이 들어온 경우 Index구성 순서상 이후에 있는 컬럼에 공급된 조건들은 작업범위를 줄이는데 작용하지 못한다. 예외상황:9i 이후부터 index skip scan

3.적용범위
•10만건 이하의 건수를 access 할때
•10만건 이상이라도 부분범위처리가 가능할때
•10만건 이상이라도 인덱스만 scan 하고 table access 가없을때
•주로 OLTP

4.HINT /*+ INDEX(테이블명 혹은 ALIAS 인덱스명) */
•실행계획
select * from emp where mgr > 7839;

-------------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
TABLE ACCESS (BY [INDEX] ROWID) OF 'T_EMP'
INDEX (RANGE SCAN) OF 'T_EMP_IDX01' (NON-UNIQUE)
 
1.발생규칙
•Unique Index를 구성하고 있는 모든 Key값에 대해서 Equal(=) 로 조건이 공급된 경우 발생한다
2.Access 방식
•해당 조건을 만족하는 값 하나만 읽는다

3.적용범위
•OLTP 의 화면에서 적용하느것이 최적임.
•한건만 읽어야 할경우.

4.Hint

- /*+ index(테이블명 또는 테이블별칭) */

-plan 상에서의 index unique scan

select *
from emp
where empno = 7790 ;

-------------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
TABLE ACCESS (BY [INDEX] ROWID) OF 'EMP'
INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE)

Data Access Pattern - Index Fast Full Scan

>발생규칙
•Where절이나 Select절에 사용된 컬럼이 모두 하나의 인덱스에 구성된 컬럼인 경우
•결합Index의 경우 최소한 한 Column이 NOT Null로 지정되어 있어야 한다.


>Access 방식
•인덱스 Leaf Block을 한번에 DB_FILE_MULTIBLOCK_READ_COUNT에서 정한 크기씩 끝까지 읽어 내려가며 결과 값의 Sort가 보장되지 않는다
•Parallel로 수행 가능하다
•Full Table Scan보다 읽어야 할 Block의 수가 적어 유리하다.


>적용범위
•FTS(FULL TABLE SCAN)과 같음.

>Hint
-/*+ index_ffs(테이블명(혹은 별칭) 인덱스명) */

>Plan 상에서의 Index Fast Full Scan

SELECT /*+ index_ffs(a emp_job_idx) */
empno, ename, job
FROM emp a
WHERE job = 'SALESMAN'

-------------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
INDEX (FAST FULL SCAN) OF 'EMP_JOB_IDX'

Data Access Pattern - Full Table Scan

1.발생규칙

-아무런 조건 없이 Table을 읽게 한 경우

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

-인덱스가 걸려있는 컬럼에 조건을 부여했을지라도 Optimizer가 Full Table Scan이 유리하다고 판단한 경우

2.Access 방식

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

-한번에 DB_FILE_MULTIBLOCK_READ_COUNT에서 정한 크기 만큼 읽는다 .

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

-Parallel로 수행 가능하다

3. 적용범위

-10만건(평균적으로) 이상을 Read 할때 --> 인덱스를 경유하면 더느림

-주로 OLAP/DSS 시스템에서 사용

-OLTP 시스템의 야간 Batch 작업

4.Hint

- /*+ full(테이블명 또는 테이블별칭) */

-plan 상에서의 full scan
select * from emp;
-------------------------------------------------
SELECT STATEMENT GOAL: CHOOSE
TABLE ACCESS (FULL) OF 'EMP'

1504 view

4.0 stars