study:oracle:datadb:1week_2
문서의 이전 판입니다!
목차
* B-tree 인덱스 설명은 http://wiki.oracleclub.com/pages/viewpage.action?pageId=1507450 에서 사진 및 내용을 인용하였습니다.^^
제2장 인덱스의 유형과 특징
- 인덱스란 말 그대로 전체 내용물 중에서 특정한 부분을 바로 찾을 수 있는 목차(目次)나 색인(索引)의 개념.
- 테이블에 저장되어있는 데이터를 좀 더 효율적이고 빠르게 찾기 위해 사용.
- 관계형 데이터베이스에서 적용하고 있는 인덱스 유형은 아래와 같음.
- B-Tree 인덱스
- 비트맵(Bitmap) 인덱스
- B-tree 클러스트 인덱스
- 해쉬(hash)클러스터 인덱스
- 리버스 키(Reverse key) 인덱스
- 비트맵 조인(Bitmap join) 인덱스
- 함수기반(Function-based) 인덱스
2.1 B-tree 인덱스
- 생성 명령어 : CREATE INDEX 인덱스명 ON 테이블명(컬럼명)
- 나무구조(Tree)처럼 가지에 해당하는 브랜치 블럭과 잎사귀에 해당하는 리프 블럭이 있다.
2.1.1 B-tree 인덱스의 구조
:——————————————————————————————————
- Unique Scan일 경우
- range Scan일 경우
- 인덱스는 구성컬럼과 ROWID로 정렬되어 있다.
- ROWID에는 로우가 저장된 블록의 주소, 로우의 슬롯번호가 기록되어 있다.
- 처리할 범위의 첫번째 인덱스로우를 브랜체블록을 통해 리프블록을 액세스한 다음 거기의 ROWID로 블록을 찾는다.
- SGA부터 찾아보고 없으면 디스크에 액세스해서 복사본을 SGA에 복사한다.
- 새롭게 액세스한 데이터블록정보를 PGA로 가져와서 해당 SQL의 처리버퍼에 넣는다 (일명 원 버퍼).
- 인덱스블록을 액세스한 내용을 PGA버퍼에서 찾아 다른 조건까지 검증하여 성공한 로우만 운반단위로 보낸다 만약 클러스터링 팩터가 좋다면 여러건의 인덱스 스캔을 하나의 버퍼에서 처리할 수 있다.
- PGA버퍼에서 찾을 수 없다면 다시 다른 블록을 SGA에 액세스하여 새로운 블럭을 담고 위의 처리를 반복수행한다.
- 리프블록에서 액세스한 로우가 처리범위를 넘으면 처리를 종료한다.
- ROWID의 구성
- rowid라는 가상 컬럼에 저장된다.
- Single row access를 위한 row 고유한 주소
- 10자리로 구성
:——————————————————————————————————
2.1.2 B-tree 인덱스의 조작(Operation)
- 인덱스 생성(Creation)
- 테이블을 액새스하여 정렬을 수행.
- 정렬된 결과를 인덱스 세그먼트의 리프 블록에 기록하기 시작.
- 리프블록이 PCTFREE에 도달하여 새로운 블록을 요구하게 되면 브랜치블록을 생성.
- 리프블록이 증가함에 따라 브랜치블록도 채워져 가다 블랜치블록이 PCTFREE에 도달하면 새로운 리프블록과 새로운 브랜치블록을 생성할때 루트블록이 생성된다.
- 새로운 브랜치블록이 만들어질 때마다 루트블록에 브랜치블록의 DBA정보를 기록한다.
- 위와 같은 방법으로 인덱스가 저장되기 때문에 인덱스 블럭에 많은 로우를 담게 될 경우 리프 블럭 감소, 브랜치 블럭 증가 둔화(블럭의 깊이 감소)
- 최대한 인덱스 컬럼의 수를 줄인다.
- 큰 블럭 사이즈(DB_BLOCK_SIZE)를 지정.
- PCTFREE를 최소로 정의.
- 압축을 활용하는 방법
CREATE INDEX ord_customer_idx ON orders (customer_id, sales_id) COMPRESS 1;
:——————————————————————————————————
- 인덱스 블럭의 분할(SPILT)
- 인덱스 로우는 정렬이 되어 저장 되어야 하는 이유 때문에 이미 생성된 구조에 새로운 로우가 삽입되면 기존의 위치에 파고 들어가는 문제 발생
- 마지막 값이 삽입되는 경우 : 그림처럼 PCTFREE에 도달한 블럭일 경우엔 새로운 블럭에 등록된다.
- 중간 값이 삽입되는 경우 : PCTFREE가 초과하게 되므로 분할이 발생하는데 어차피 2개의 블럭으로 수정되므로 2/3만 채우도록 하면서 양쪽을 모두 재편하게 됨(또 다른 중간 값이 들어와 계속 분할 되는 것을 방지하기 위함).
- 하지만 분할이 일어난 블럭에 새로운 값이 들어오지 않으면 저장공간 낭비를 초래하게 되고 이를 해결하기 위해선 인덱스를 재생성하는 방법뿐이다.
:——————————————————————————————————
- 데이터의 삭제 및 갱신
- 데이터를 삭제했을 경우 테이블의 로우는 제거되지만 인덱스의 로우는 삭제되었다는 표시(flag)만 추가된다.(저장공간낭비와 스캔시 액세스 블럭 증가)
- 한 리프 블럭이 모두 삭제 되었을 경우 브랜치 블럭에 해당 리프 블럭을 가리키는 로우도 삭제 표시가 된다.
- 갱신할 경우 삭제와 삽입이 발생.
- 이러한 이유로 수정이 빈번하지 않는 컬럼을 인덱스로 사용권장.
- 데이터처리(DML)가 많이 수행되는 테이블은 정기적으로 재생성을 할 필요가 있다.
:——————————————————————————————————
- 인덱스를 경유한 검색
- lmc는 브랜치 블럭의 첫 번째 로우의 값보다 적은 값을 갖는 하위의 블럭의 주소정보(dba:data block address)를 말한다.
- 루트 블록을 찾는다.
- 주어진 값보다 같거나 최소값을 찾는다.(찾는값 >= 인덱스값)
- 찾는 값 < 인덱스 값 (Lmc에 있는 dba로 이동)
- 찾는 값 = 인덱스 값 (해당 dba로 이동)
- 찾는 값 > 인덱스 값 (검색 후 찾는 값 = 인데스 값이면 해당 dba로 이동 그렇지 않으면, 찾는 값 < 인데스 값을 만족하는 인덱스 최소값)
- 리프 블록을 찾을 때까지 ② 의 단계를 반복해서 수행.
- 리프 블록에서 주어진 값을 가진 키를 찾아 존재하면 ROWID를 이용해 테이블을 액세스하고, 그렇지 않으면 'No Data found'로 결과 반환 만약, col2의 조건을 'ACC'가 아닌 'AC%'로 바꾸면 Col1 = 'B'이면서 Col2 = 'AC'보다 같거나 큰 것에서 스캔을 시작, 'AD' 보다 작으면 테이블을 액세스하고, 그렇지 않으면 종료한다.
:——————————————————————————————————
B-tree인덱스의 문제점
- B-TREE인덱스에서는 실제 컬럼 값을 인덱스에도 보관하고 있어야 한다는 점이 대용량 데이터를 관리할 때 부담이 된다.
- B-TREE인덱스 컬럼값의 분포도가 좋아야 한다는 점
- 결합인덱스에서 조건을 사용하지 않는 컬럼이나 =조건이 아닌 컬럼이 결합인덱스 중간에 있으면 액세스효율성이 떨어진다는 점
- 다양한 액세스패턴을 수용하기 위해 많은 인덱스가 필요할 수 있다는 점
- NOT이나 NULL을 사용하거나 복잡한 OR조건에서는 인덱스의 성능을 보장받지 못한다는 점
2.2 비트맵(Bitmap) 인덱스
- 컴퓨터에서 사용하는 최소의 단위인 비트를 사용하여 컬럼 값을 저장하고 이를 이용하여 rowid를 자동으로 생성하는 인덱스 방법으로 비트를 직접 관리하므로 저장공간이 감소하고 비트연산이 용이 하다는 장점이 있다.
- 생성 명령어 : CREATE BITMAP INDEX … ON …
2.2.1 비트맵(Bitmap) 인덱스의 탄생 배경
- B-TREE인덱스가 가지는 문제점을 독립적으로 구성된 각각의 비트맵 인덱스가 조합되어 해결할 수 있다.
2.2.2 비트맵(Bitmap) 인덱스의 구조와 특성
구조
생성절차
- 인덱스를 생성하고자 하는 컬럼의 값들을 찾기 위해 테이블 스캔을 한 후
- bitmap generator에 의해 컬럼값, start rowid, end rowid , bitmap을 갖는 인덱스 엔트리를 생성한다.
- 2단계에서 생성된 Bitmap들을 B-tree구조에 넣기 쉽도록 key값과 start rowid 순으로 정렬한다.
- 마지막 단계에서는 정렬된 인덱스 엔트리들을 단순히 B-tree구조로 삽입한다.
특성
- 비트를 저장할 때는 '선분 형태(Start rowid ~ End rowid)'로 저장을 하므로 일종의 압축 개념이 되며, 키 압축(Key Compression)이 적용되어 저장 공간이 매우 절약된다.
- 비트맵 연산을 통해 처리하므로 OR 연산이 가능하다.
- NULL 값도 BIT를 구성하고 있어 NULL 및 NOT 조건검색이 가능하다.
- 수정이 빈번하게 발생하는 컬럼은 인덱스의 크기가 크게 증가하고 블록레벨 잠금(Block Level Locking)으로 인해 많은 부하가 유발될 수 있다.
- 데이터 웨어하우스 업무에 주로 활용된다.
제한사항
- Partition table에서 Global Index에는 Bitmap Index를 만들 수 없다.
- Local Index를 구성할 경우에는 Bitmap Index로 만들 수 있으나, 여러 파티션에 걸쳐있는 Global Index를 구성할 때는 Bitmap Index를 만들 수 없다.
- Bitmap Index는 RBO(rule base optimizer) mode에서는 사용될 수 없다.
- Bitmap Index는 통계치에 의하여 산출된 cost를 기반으로 Bitmap Index의 사용여부를 결정하기 때문에 Optimizer Mode는 반드시 CBO(cost based optimizer) Mode인 ALL_ROWS 또는 FIRST_ROWS로 지정되거나 , CHOOSE mode인 경우 해당 object는 ANALYZE 명령을 통하여 통계정보를 생성해 주어야 한다.
- IOT(Index Organized Table)에는 rowid를 가지고 있지 않기 때문에 rowid range로 표현되는 Bitmap Index를 사용할 수 없다. 그러나 Oracle9i부터는 ALTER TABLE .. MOVE MAPPING TABLE과 같이 mapping table을 이용하여 Bitmap Index를 사용할 수 있다.
2.2.3 비트맵(Bitmap) 인덱스의 엑세스
비트맵 인덱스 사용시 실행계획 오퍼레이션
NOT,OR 이 포함된 쿼리에 실행계획
- COL1 인덱스에서 '123'인 비트맵을 엑세스하고,COL2인덱스에서 'ABC'인 비트맵을 엑세스하여 감산연산을 수행한다(BITMAP MINUS)
- COL2에서 NULL인 비트맵과 1의 결과를 다시 감산연산을 수행한다(BITMAP MINUS)
- COL3 < 100 인 비트맵을 읽어 머지(BITMAP MERGE)를 수행하여 하나의 비트맵을 만든다.
- 2와 3에서 수행한 결과에 대해 OR연산(BITMAP OR)을 수행하여 조건을 만족하는 최종결과 비트맵을 만들고 ROWID로 변형하여 테이블을 엑세스 한다.
- 제한사항
- 파티션테이블에서 Global Index에는 비트맵인덱스를 만들 수 없다.
- 비트맵인덱스는 RBO(Rule Base optimizxer) mode에서는 사용될 수 없다.
B-Tree 인덱스와 비트맵(Bitmap)인덱스의 비교
study/oracle/datadb/1week_2.1273122532.txt.gz · 마지막으로 수정됨: 저자 ahmax










