2009년 7월 6일 월요일

Falcon: 인덱스

인덱스 구성은 InnoDB와 Falcon에서 크게 차이가 난다.  InnoDB는 클러스터드인덱스(Oracle에서는 색인 구성 테이블에 상당)이 채용되어 있어 프라이머리 키용의 인덱스가 특별 관리되고 있다.

프라이머리키에 따른 인덱스를 프라이머리 인덱스 , 그 외에의 인덱스를 세컨더리 인덱스라 부른다. 

프라이머리 인덱스는  프라이머리 키값을 키로하고 나머지 컬럼값을 취득한다. 

따라서 세컨더리 인덱스를 이용해서  비 인덱스 컬러값을 취득할 때 세컨더리 인덱스를 보고 프라이머리 키 값을 찾은 후 프라이머리 인덱스를 보고 컬럼값을 취득하는 2단계 처리가 수행된다. 

그리고 프라이머리 키 검색은 매우 빠르다. 

Falcon에서는 클러스터드 인덱스를 채용하고 있지않다. 
인덱스는 B-Tree색인을 개량한 것으로 인덱스의 컬러값을 키로하고 내부적으로 관리하고 있는 유니크한 행번호를 취득하는 것으로 되어있다. 

비트맵 검색
기존의 B-Tree인덱스에서는 추출조건을 만족하는 레코드가 여러개 있을 경우 

최초의 레코드를 취득하기 위한 인덱스 트리를 검색
↓
대응하는 데이터 부분을 읽기
↓
다음 레코드를 취득하기 위한 인덱스 트리를 검색
↓
대응하는  데이터 블록을 읽기
↓
...
처럼 인덱스 부분과 데이터 부분을 왔다갔다하게 된다. 
캐쉬에 실을 수 없는 대량 데이터를 다룰 경우 디스크의 랜덤 I/O가 문제가 되는 경우가 많다. 

Falcon에서는 이런 구현을 하지 않는다. 
구체적으로  우선 인덱스트리를 검색해 추출조건을 만족하는 전 레코드의 행번호를 취득한다. 
이 행번호에는 레코드의 물리적인 배치정보가 포함되어 있다.
다음에 물리적으로 배치순을 소트해서 그 순번대로 데이터를 취득하는 것이다. 

이렇게 하므로써 가장 병목현상이 나기 쉬운 디스크의 seek대기 시간이나 회전 대기 시간을 줄이게 된다. 

한개의 테이블에 대해서 프라이머리 키 검색이나 유니크 키 검색으로 레코드를 단 한개를 취득하는 것 같은경우에는 우수하지는 않지만 IN문 이나 OR문등의  복수 레코드 추출에서는 효과가 있다.  같은 이유로  서브 쿼리나  조인에서도 효과를 기대할 수 있다. 

인덱스관리
Falcon에서는 인덱스 값을 갱신하는 처리(INSERT/UPDATE/DELETE)를 실행한 경우에 인덱스 본체에 갑자기 반영을 하는 것이 아니라 본체 인덱스와는 별도로 전용메모리 영역에 써넣는 구성을 하고 있다.  이 전용 메모리 영역은 트랜잭션마다 독립해서 확보된다. 

본체 인덱스로의 반영은 커밋할 때 소트가 끝난 상태에서 수행된다.  이 때문에 대량 데이터를 한개의 트랜잭션에서 다루는 처리나 롤백등의 부하가 매우 적게 된다. 

한편 인덱스를 조사하는 처리는 본체인덱스만 아니라 각 트랜잭션에서 관리하는 메모리 영역도 참조할 필요가 있기 때문에  오버헤드가 다소 커지는 경향이 있다.