h3.비트맵 인덱스 기본 구조
row#0[ 8001] flag: ------, lock:0, len=35
col 0; len 2; (4): 42 4c 55 45 *?* *키 값 : BLUE*
col 1; len 6; (6): 01 00 9f 4c 00 00 *? 시작 rowid*
col 2; len 6; (6): 01 01 a4 03 01 47 *? 종료 rowid*
col 3; len 15; (15): 00 c0 ae bb fa 02 c1 a1 10 c1 94 19 c2 dc 07 *? 비트맵*
h4.비트맵 위치와 rowid 매핑
SQL> show parameter block_size;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL> create table t1 ( c )
2 pctfree 0
3 as
4 select 'a' from dual connect by level <= 100000;
테이블이 생성되었습니다.
SQL> select min(count(*)), max(count(*)), avg(count(*))
2 from t1
3 group by dbms_rowid.rowid_block_number(rowid);
MIN(COUNT(*)) MAX(COUNT(*)) AVG(COUNT(*))
------------- ------------- -------------
720 730 729.927007
-- 5Byte를 늘려서 다시 테스트
SQL> create table t2 ( c )
2 pctfree 0
3 as
4 select lpad('a', 5) from dual connect by level <= 100000;
테이블이 생성되었습니다.
SQL> select min(count(*)), max(count(*)), avg(count(*))
2 from t2
3 group by dbms_rowid.rowid_block_number(rowid);
MIN(COUNT(*)) MAX(COUNT(*)) AVG(COUNT(*))
------------- ------------- -------------
720 730 729.927007
florr(9500/730) = 13 -> 14번째 블록
mod(9500,730) = 10 -> 10번째 레코드
730 * 13 + 10 = 9,500
h4.키 값의 수가 많을 때
h4.키 값별로 로우 수가 많을 때
h4.비트맵 압축
h3.비트맵 인덱스 활용
-- 상품 테이블의 '크기'와 '색상' 두 컬럼에 각각 비트맵 인덱스가 있는 상태에서 아래와 같은 쿼리를 수행
select * from 상품
where (크기 = 'SMALL' or 크기 is null)
and 색상 = 'GREEN'
h3.RECORDS_PER_BLOCK
-- 100만개 레코드를 갖는 T 테이블을 생성
SQL> create table t ( x number, y char(1) ) pctfree 99 pctused 1;
테이블이 생성되었습니다.
SQL> insert into t
2 select mod(rownum,3), 'x' from dual connect by level <= 1000000;
1000000 개의 행이 만들어졌습니다.
SQL> commit;
커밋이 완료되었습니다.
-- Block당 레코드의 개수 확인
SQL> select min(count(*)), max(count(*)), avg(count(*))
2 from t
3 group by dbms_rowid.rowid_block_number(rowid);
MIN(COUNT(*)) MAX(COUNT(*)) AVG(COUNT(*))
------------- ------------- -------------
1 7 6.999958
-- 인덱스를 만들고 크기를 측정하면, 총 256개 블록이 할당돼 2MB공간을 차지
SQL> create bitmap index t_idx on t(x);
인덱스가 생성되었습니다.
SQL> select extents, blocks, bytes/1024 "SIZE(KB)"
2 from user_segments
3 where segment_name = 'T_IDX';
EXTENTS BLOCKS SIZE(KB)
---------- ---------- ----------
17 256 2048
-- 인덱스를 삭제 후 T 테이블을 스캔하여 블록당 최대 레코드 개수를 조사
SQL> drop index t_idx;
인덱스가 삭제되었습니다.
SQL> alter table t minimize records_per_block;
테이블이 변경되었습니다. -> 작업이 완료되면, T 테이블에는 블록당 최대 7개 레코드만 저장됨
-- 비트맵 인덱스를 만들면, 오라클은 블록당 최대 7개 레코드가 담기는 것을 기준으로 키 값마다 [블록수 * 7] 만큼의 비트를 할당
SQL> create bitmap index t_idx on t(x);
인덱스가 생성되었습니다.
SQL> select extents, blocks, bytes/1024 "SIZE(KB)"
2 from user_segments
3 where segment_name = 'T_IDX';
EXTENTS BLOCKS SIZE(KB)
---------- ---------- ----------
10 80 640
- 강좌 URL : http://www.gurubee.net/lecture/3205
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.