인덱스는 만능이 아니다.
오히려 느려질 수 있다. 이전 포스팅에서 index range scan, index full scan의 단점에 대해서 언급했다.
인덱스 리프노드에는 RowID가 존재하고, 이 후에 테이블 (블록) 에 접근해서 정보를 가져온다.
RowID는 물리적주소라기보다는 논리적 주소에 가깝다.
어떤 파일에, 어떤 블록에, 몇번째 레코드에 저장되어 있는지 적혀있다. 결국 Disk I/O를 진행한다는 것이 특징이다.
가끔 포인터와 헷갈리는 경우가 있는데 포인터가 전화번호라면, RowID는 주소라고 비유되어있다. 즉 한번에 연락이 닿기가 쉽지 않다는 것이다.
버퍼캐시저장소에 RowID 를 저장한다.
버퍼캐시저장소는 해시구조로 되어있어서, RowID를 이용해 버퍼헤더정보를 통해 한번에 버퍼 블록을 찾아갈 수 있다.
인덱스 리프노드에 RowID들이 저장되어있다. 만일 DLL로 연결되어있는 리프노드들은 주위에 있는 녀석들끼리 비슷한 블록주소에 위치한다면? 데이터 접근속도가 더 빠를 것이다.
이것을 인덱스 클러스터링 팩터라고 한다.
군집화가 잘 되어있으면 테이블 액세스량에 비해 블록 I/O가 적게 발생할 수 있다.
이게 가능한 이유는 오라클은 테이블 엑세스할때, 래치획득과 해시체인 스캔과정을 거쳐 어렵게 찾아간 테이블 블록의 포인터를 바로 해제하지 않고, 일단 유지한다. 이것을 버퍼 Pinning 이라고 한다.
말그대로 인덱스를 사용할지 말지에 대해 결정하는 행위를 말한다.
인덱스 사용이 느려지는 경우는 총 2가지가 있다.
- TABLE FULL SCAN은 시퀀셜인반면, 인덱스 ROWID는 랜덤 엑세스이다.
- TABLE FULL SCAN은 Multiblock I/O인 반면, 인덱스 ROWID는 SINGLEBLOCK I/O이다.
버퍼캐시 메모리의 양이 점점 증가하는 추세이지만, 데이터 접근횟수가 100만건 이상인 경우에는 캐시 히트율이 극히 낮아질 수 있다. 따라서 잘 고려해서 사용하도록 한다.
한 블록에 모두 데이터를 담을 수 없을 때는 새로운 블록을 할당해서 클러스터 체인으로 연결한다(인덱스 구조 테이블을 파티셔닝한것처럼 구조를 이해하자)
해시구조로 블록 파티셔닝을 진행할 수 있다.