2009년 7월 6일 월요일

Falcon: 인덱스

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

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

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

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

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

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

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

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

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

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

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

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

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

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