이 글에서는 오라클 데이터베이스(DB)의 네 가지 인덱스 중 가장 광범위하게 쓰이는 B*TREE 인덱스를 사용할 때 고려해야 할 것들을 살펴본다.
B*TREE 인덱스에서 고려해야 할 것 중 하나는 랜덤 액세스의 양이다.
인덱스가 적용된 DB에서 필요한 값을 찾을 때에는 가장 먼저 테이블을 조회하게 된다. 이러한 조회 과정에서 발생하는 I/O가 랜덤 액세스이기 때문에 B*TREE 인덱스를 사용할 때에는 랜덤 액세스의 양을 특히 신경써야 한다. 만약 랜덤 액세스의 양이 지나치게 많으면 B*TREE 인덱스를 이용하지 않는 게 좋다.
OR 조건은 <그림 2>처럼 조건이 추가될 때마다 처리 대상이 계속 확대된다. 그렇기 때문에 옵티마이저는 테이블 전체 스캔(Full Scan)을 수행하는 게 유리하다고 판단한다.
그러므로 OR 조건을 사용하는 많은 경우에 B*TREE 인덱스 대신 테이블 전체 스캔으로 수행된다. B*TREE 인덱스를 스캔하더라도 OR로 인해 처리 대상 범위가 증가해 랜덤 액세스가 크게 증가하게 된다.
AND 연산은 조건이 추가될 때마다 처리 대상 집합이 감소한다. AND 연산자가 계속 추가되고 해당 조건으로 구현된 B*TREE 인덱스가 존재한다면 옵티마이저는 해당 인덱스를 이용해 SQL을 수행하게 된다.
처리 대상 집합이 감소하면 인덱스를 스캔하는 양과 랜덤 액세스도 감소하게 된다. B*TREE 인덱스는 OR 연산자의 경우 비트맵(Bitmap) 인덱스에 비해 불리하다.
OR 연산을 B*TREE 인덱스로 처리해야 한다면 경우에 따라 IN을 사용한 SQL 튜닝을 통해 최적화할 수 있다. 이처럼 B*TREE 인덱스는 해당 인덱스로 구성되는 데이터의 전체 분포도에 중요하다.
B*TREE 인덱스에서 많은 데이터를 액세스한 후 테이블을 액세스해야 할 경우 B*TREE 인덱스를 이용하면 성능 저하가 발생한다.
비트맵 인덱스는 B*TREE 인덱스와 달리 비트맵, 즉 0 또는 1로 인덱스를 관리한다. 분포도가 낮은 컬럼에 적용할 때 효과를 기대할 수 있다.
분포도가 낮은 대표적인 예는 성별 컬럼이다. 성별 컬럼은 남자, 여자 둘 중 하나의 값만을 가진다. 이러한 컬럼을 분포도가 낮다고 말한다. 이런 컬럼은 B*TREE 인덱스보다는 비트맵 인덱스를 이용하는 게 액세스 성능 측면에서 더 유리하다.
<그림 4>의 비트맵 인덱스를 살펴보자. 기본 구조는 B*TREE 인덱스와 유사하다. 루트 블록과 브랜치 블록은 B*TREE 인덱스와 동일하며 다른 부분은 리프 블록에 저장되는 인덱스 엔트리다.
B*TREE 인덱스는 < 인덱스 Key, ROWID>가 인덱스 엔트리에 저장됐지만 비트맵 인덱스는 해당 인덱스 컬럼에 대한 비트맵이 <그림 4>처럼 저장된다.
<그림 4> 비트맵 인덱스의 리프 블록을 확인해보면 컬럼 값 또는 Key, Start ROWID, End ROWID, 비트맵으로 구성돼 있다.
비트맵 인덱스는 이처럼 해당 값을 비트맵으로 구성해 리프 블록을 생선한다. 비트맵 인덱스의 구조에 대해 좀 더 자세히 살펴보자.
<그림 5>에서 이가혜라는 데이터는 여자이므로 남자 비트맵에는 0을 저장하고, 여자 비트맵에는 1을 저장한다. 그 결과, 남자 비트맵의 비트 값은 010111, 여자 비트맵의 비트 값은 101000이 된다.
남자 비트맵과 여자 비트맵을 서로 비교하면, 첫 번째 데이터는 여자이고, 두 번째 데이터는 남자다. 세 번째느 여자인 것을 확인할 수 있다. 그렇기 때문에 모든 비트맵을 조합하면 어떤 값을 저장하는지 알 수 있다.
지금부터는 비트맵 인덱스를 이용한 데이터 액세스를 확인해보자.
SELECT 이름, 주소 FROM 고객 WHERE 성별='여자';
<그림 5>의 고객 테이블은 대용량 테이블이며 성별에 비트맵 인덱스가 적용돼 있다고 가정하자. <리스트 1> SQL은 과연 어떤 과정을 거쳐 데이터에 액세스할까?
① 성별이 여자라는 조건을 설정했기 때문에 성별 비트맵 인덱스의 리프 블록의 비트맵 중 여자 비트맵을 액세스하게 된다.
② 1 단계에 의해 101000이라는 여자 비트맵(Bitmap)을 액세스한다.
③ 해당 비트맵만 추출하면 몇 번째 데이터가 여자인지를 알 수 있다. 이 케이스의 경우 해당 테이블의 첫 번째와 세 번째 데이터가 성별이 여자인 데이터다.
④ 해당 테이블의 Start ROWID와 End ROWID를 이용해 첫번째 데이터와 세번째 데이터의 ROWID를 생성한다.
⑤ 4 단계에서의 ROWID를 이용해 고객 테이블을 액세스함으로써 결과를 추출한다.
이러한 과정으로 비트맵 인덱스를 액세스해 데이터를 추출하게 된다.
- 강좌 URL : http://www.gurubee.net/lecture/2957
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.