비트맵 인덱스(Bitmap Index)
B*Tree 인덱스
- B-tree 인덱스는 실제 컬럼 값을 인덱스에도 보관함으로써 중복이 생긴다.:NAMESPACE PREFIX = O />
- B-tree 인덱스는 컬럼의 분포도가 좁아야 최적의 성능을 발휘 하므로 분포도가 넓을 경우 불리
- b-tree 인덱스는 'null', 'not'을 사용한 부정형 조건 복잡한 'or'등에서 제 성능을 발휘하지 못함
· 대량 데이터 환경, 복합인덱스의 경우 Index위한 데이터 중복저장으로 저장공간의 낭비
Bitmap 인덱스
· DB Index를 Bit 단위로 저장하여 B-Tree 인덱스 한계를 극복하여 대량의 자료 조회에 적합한 Index 유형
· DW와 같은 정보계 시스템에서 다량의 데이터를 조회하는 경우, 데이터의 존재 여부를 0,1로 표현하여 다량의 데이터를 빠르게 조회
· 컴퓨터에서 사용하는 최소단위인 비트를 이용, 컬럼 값을 저장하고 이를 이용 ROWID를 자동으로 생성하는 방법
· 분포도가 나쁜 컬럼 값에 대한 Index Access가 빠름, OR 질의에 용이함
· 빈번하게 Update되는 환경에는 Leaf Block 갱신으로 인해 부적합하다. 하나의 인덱스 엔트리를 수정하게 되면 그인덱스가 가리키는 모든 ROW에 락을 건다.
·
:NAMESPACE PREFIX = V />
B-tree 인덱스의 리프블럭(leaf block)은 Index key value + rowid 로 구성이 되어 있지만, Bitmap Index는 Index key value + Start Rowid + End Rowid + Bitmap 엔트리로 구성되어 있다. 1개의 index값이 테이블상의 여러 개의 record를 표현하기 때문에 DML문을 사용할 경우 row level locking을 지원할 수 없다
Start rowid 와 End rowid 의 사이에 있는 모든 row수만큼 Bitmap이 표현되어야 하지만, 오라클에서는 내부적인 압축 알고리즘을 사용하여 Bitmap을 생성하기 때문에 모두 표현되지 않는 경우도 있다 |
[구조]
bitmap인덱스의 leaf block 구조는 key, start rowid, end rowed, bitmap으로 구성되어 있다. (비트리 인덱스의 경우 key, rowid로 구성) 비트맵 인덱스의 경우 하나의 인덱스 엔트리에 여러 개의 rowid가 있어 인덱스키와 rowid가 쌍으로 이루어진 B*Tree 인덱스와는 다르다.
[비트맵 인덱스 생성 절차]
인덱스를 생성하고자 하는 컬럼의 값들을 찾기 위해 테이블 스캔을 한 후
bitmap generator에 의해 컬럼값, start rowid, end rowid , bitmap을 갖는 인덱스 엔트리를 생성한다.생성된 Bitmap들을 B-tree구조에 넣기 쉽도록 key값과 start rowid 순으로 정렬하며 마지막 단계에서는 정렬된 인덱스 엔트리들을 단순히 B-tree구조로 삽입한다.
bitmap generator에 의해 컬럼값, start rowid, end rowid , bitmap을 갖는 인덱스 엔트리를 생성한다.생성된 Bitmap들을 B-tree구조에 넣기 쉽도록 key값과 start rowid 순으로 정렬하며 마지막 단계에서는 정렬된 인덱스 엔트리들을 단순히 B-tree구조로 삽입한다.
[실습]
drop table bitmaptest:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
create table bitmaptest (
no number,
area varchar2(20)
)
no number,
area varchar2(20)
)
--'이천만건 입력(area 컬럼의 분포도는 20% 정도)
DECLARE
v_counter NUMBER := 1;
BEGIN
WHILE (v_counter <=20000000) LOOP
insert into bitmaptest values (v_counter, '서울');
v_counter := v_counter + 1;
insert into bitmaptest values (v_counter, '수원');
v_counter := v_counter + 1;
insert into bitmaptest values (v_counter, '부산');
v_counter := v_counter + 1;
insert into bitmaptest values (v_counter, '대구');
v_counter := v_counter + 1;
insert into bitmaptest values (v_counter, '광주');
v_counter := v_counter + 1;
END LOOP;
commit;
END;
commit;
END;
select count(*) from bitmaptest;
--area 컬럼에 B*Tree 인덱스를 만들고 검색 시간을 측정해보자.
create index idx_bitmaptest_btree_area on bitmaptest(area);
SQL> select count(*) from bitmaptest where area = '광주';
COUNT(*)
----------------
4000000
----------------
4000000
1 rows selected.
SQL Execution Time > 00:00:01.965
Total Elapsed Time > 00:00:01.965
Total Elapsed Time > 00:00:01.965
idx_bitmaptest_btree_area 인덱스를 이용했으며. 거의 2초 가까이 걸린다.
이번에는 or 연산을 이용하여 where절에 조건을 주자.
SQL> select count(*) from bitmaptest
where area = '서울'
or area = '대구';
COUNT(*)
----------------
8000000
----------------
8000000
1 rows selected.
SQL Execution Time > 00:00:02.265
Total Elapsed Time > 00:00:02.281
Total Elapsed Time > 00:00:02.281
인덱스 이용했으며 2초 조금 더 걸린다.
drop index idx_bitmaptest_btree_area;
이번에는 비트맵 인덱스를 생성하자.
create bitmap index idx_bitmaptest_bitmap_area on bitmaptest(area);
SQL> select count(*) from bitmaptest where area = '광주';
COUNT(*)
----------------
4000000
----------------
4000000
1 rows selected.
SQL Execution Time > 00:00:00.015
Total Elapsed Time > 00:00:00.015
Total Elapsed Time > 00:00:00.015
엔터키 입력하자 마자 결과 나옴, 인덱스 생성 시간도 비트리 인덱스 보다 훨씬 빠름
이번에는 or 연산을 해보자.(엔터키 누르자 마자 결과 나옴)
SQL> select count(*) from bitmaptest
where area = '서울'
or area = '부산';
COUNT(*)
----------------
8000000
----------------
8000000
1 rows selected.
SQL Execution Time > 00:00:00.172
댓글 없음:
댓글 쓰기