Bitmap
배경
- B Tree 인덱스의 문제점
- 실제 컬럼 값을 인덱스에도 보관하고 있기 때문에 대용량 데이터일 경우 부담이 큼
- 컬럼 값의 분포도가 좋지 않으면 효율이 떨어짐
- 결합 인덱스에서 조건을 사용하지 않는 컬럼이나
=조건이 아닌 컬럼이 결합 인덱스 중간에 있다면 접근 효율성이 떨어짐 - 다양한 접근을 위해 인덱스가 많아질 수 있음
NOT,NULL을 사용하거나 복잡한OR조건에서는 인덱스 성능이 좋지 못함- 컬럼 값과 집합 내에서 해당 정보의 Rowid가 정렬된 형태이기에 동일 값에 대해서 물리적 주소가 다르다면 값을 중복해서 가지고 있어야 하기에 저장공간 낭비가 발생
- 테이블 컬럼 값의 길이가 크다면 인덱스 크기 또한 증가함
- 동일한 테이블에 대해 접근할 때 두 개 이상의 인덱스를 병행해서 사용함에 있어 제약사항이 많음 (결국 조합에 따른 인덱스가 많아질 수 밖에 없으며 테이블 크기보다 더 커지는 현상이 발생할 수 있음. 즉, 각각의 인덱스를 관리하는 비용이 테이블 자체를 관리하는 비용보다 커지게 될 수 있음)
구조
---------------------------------------------------------------------
| Index Entry Header | Key Value | Start Rowid | End Rowid | Bitmap |
---------------------------------------------------------------------
Entry Header : 컬럼 수와 Lock 정보를 저장
Key Value : 각 키 컬럼의 길이와 값의 쌍을 저장
Start Rowid : 시작 Rowid
End Rowid : 끝 Rowid
Bitmap : 0, 1로 이루어진 Bit 문자열 (0이라면 해당 키 값이 존재하지 않고 1이라면 해당 키 값이 존재)
B Tree의 리프 블록은 인덱스 키 값 + Rowid 로 구성이지만 비트맵 인덱스는 인덱스 키 값 + Start Rowid + End Rowid + 비트맵 엔트리 로 구성되어 있음
1개의 인덱스 값이 테이블 내의 여러 개 레코드를 표현하기 때문에 DML에서 Row Level Locking을 지원하지 못함 (Start Rowid와 End Rowid의 범위 안에 있는 모든 레코드 수 만큼 비트맵이 표현되어야하지만 오라클의 내부 압축 알고리즘을 통해 생성하기 때문에 전부 표현되지 않는 경우도 있음)
생성
- 인덱스를 생성하고자 하는 컬럼 값들을 찾기 위해 테이블 스캔
- 비트맵 Generator가 컬럼 값, Start Rowid, End Rowid, 비트맵을 갖는 인덱스 엔 트리를 생성
- 생성된 비트맵들을 B Tree 구조에 넣기 쉽도록 키 값과 Start Rowid 순으로 정렬
- 정렬된 인덱스 엔트리들을 B Tree 구조로 삽입
CREATE BITMAP INDEX owner_name.index_name ON owner_name.table_name(column_name) TABLESPACE tablespace_name;
접근
비트맵이 해당 조건에 존재한다면 비트 연산을 통해 Rowid를 추출함
사용
- 비트맵 인덱스는 낮은 카디널리티 데이터에 적합 (즉,
DISTINCT가 적은 데이터) - 또한 낮다는 기준은 결과 집합 크기에 상대적이므로 생각보다 여러 곳에 적용 가능 (예를 들어 억 단위의 데이터 중 천 단위의 카디널리티는 상대적으로 낮다고 볼 수 있음)
- 집계 처리에 적합
단점
- OLAP에서는 적합한 인덱스이나 OLTP에서는 적합하지 않음 (하나의 비트맵 인덱스 키가 많은 로우랑 연결되어 있기 때문에 하나의 세션에서 인덱스 엔트리를 수정하게 되면 그 인덱스가 포인터하고 있는 모든 로우에 대해 Lock이 발생하기 때문)
비트맵 조인 인덱스
테이블에 하나의 비트맵 인덱스가 존재할 때 Optimizer는 B Tree 인덱스를 사용하여 비트맵 접근 경로 (Bitmap Access Path) 를 사용할 지를 고려할 수 있음. 이 때 생성되는 접근 경로는 B Tree와 비트맵을 결합한 형태가 될 수 있는데 이를 비트맵 조인 인덱스라 함
많은 수의 Dimension 테이블을 가지고 있는 경우 유용할 수 있으며 일반적인 비트맵 인덱스만을 사용할 때 발생하는 Bitwise 연산이 필요 없어짐
비트맵 조인 인덱스는 두 개 이상의 테이블의 조인 결과에 대해 비트맵 인덱스를 생성할 수 있게 해주며 조인되어야 하는 데이타의 양을 미리 제한하고 Rowid를 압축해 유지하므로 디스크 IO를 효율적으로 관리할 수 있음
전제 조건으로서 조인 조건에 다른 테이블의 기본 키 또는 유니크 키 조인이 포함되어 있어야 함
제한
스탠다드 에디션에서는 사용 불가능