IT

[Oracle] 오라클 Index Combine, Index Combination, 인덱스 동시에 사용하기

정미나 2018. 11. 29. 17:30

SELECT *

  FROM ORD E 

 WHERE ORD_DT='20120112

   AND BRANCH_CD='BR00000199';

위와 같은 쿼리가 있을 때 ORD 테이블이 [ORD_DT+BRANCH_CD] 컬럼으로 이루어진 결합인덱스를 갖고 있다면 정말 Perfect 하겠지만

ORD_X01 > ORD_DT

ORD_X02 > BRANCH_CD

이렇게 각각의 단일 인덱스만을 갖고 있다면 우리는 둘 중 어떤 인덱스를 타게 하는 것이 좋을지 고민하지 않을 수 없다. (물론 대부분의 경우 그냥 옵티마이저의 판단에 맡길테지만..)

이런 경우 Index Combine을 사용하면 고민할 필요 없이 두 개의 인덱스를 모두 사용할 수 있다.

SELECT /*+ index_combine(e ord_x01 ord_x02) */ *

  FROM ORD E 

 WHERE ORD_DT='20120112

   AND BRANCH_CD='BR00000199';



실행계획을 살펴보자.

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

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

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

|   0 | SELECT STATEMENT                 |         |      1 |    100 |00:00:00.01 |     222 |

|   1 |  TABLE ACCESS BY INDEX ROWID     | ORD     |      1 |    100 |00:00:00.01 |     222 |

|   2 |   BITMAP CONVERSION TO ROWIDS    |         |      1 |    100 |00:00:00.01 |     134 |

|   3 |    BITMAP AND                    |         |      1 |      1 |00:00:00.01 |     134 |

|   4 |     BITMAP CONVERSION FROM ROWIDS|         |      1 |      1 |00:00:00.01 |     110 |

|   5 |      SORT ORDER BY               |         |      1 |  20263 |00:00:00.01 |     110 |

|*  6 |       INDEX RANGE SCAN           | ORD_X01 |      1 |  20263 |00:00:00.01 |     110 |

|   7 |     BITMAP CONVERSION FROM ROWIDS|         |      1 |      1 |00:00:00.01 |      24 |

|*  8 |      INDEX RANGE SCAN            | ORD_X02 |      1 |   6733 |00:00:00.01 |      24 |

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

순서: 6 → 5 → 4 → 8 → 7 → 3 → 2 → 1


일반 B*Tree 인덱스를 스캔하면서 각 조건을 만족하는 레코드의 RowID 목록을 얻어 비트맵 인덱스 구조를 만든 다음 ORD_X01의 비트값도 1이고 ORD_X02의 비트값도 1인 RowID만을 획득하여 테이블에 access하는 원리임을 실행계획을 통해 알 수 있다.

비트맵 인덱스 구조를 만들어야하는 수고로움이 있으므로 인덱스 하나만을 사용했을 때 비효율적인 테이블 랜덤 액세스가 많이 발생하는 경우에만(액세스 된 레코드가 필터 조건에 의해 많이 버려지는 경우) 사용하도록 하자.

 [Oracle] 오라클 인덱스 구조 - Bitmap Index, 비트맵 인덱스 자세히 보기