아래<그림>은 클러스터드 인덱스가 없는 넌 클러스터드를 나타낸다. 첫 번째 레벨과 두 번째 레벨까지의 노드들은 인덱스 페이지들이며, 가장 하위의 것은 트리의 리프 레벨 노드들이 아니라 무작위로 저장되어 있는 데이터 페이지들이다. 그림에서는 intermediate레벨 노드들은 존재하지 않고 루트 노드와 리프노드로 직접 구성되어 있다. 리프 노드들은 데이터 페이지로의 포인터(이를 Row ID 혹은 RID(Relative Identifier)라고 부르기도 한다.)를 링크하고 있다.


이렇게 실제 데이터를 가져오기 위해서 리프 노드에서 데이터 페이지로 이동하는 것을 포인터 점프(Pointer Jump)라고 부른다. 클러스터드 인덱스에서는 리프 레벨이 데이터 페이지이므로 이러한 포인터 점프가 필요 없다. 포인터 점프는 쿼리의 퍼포먼스에 영향을 미칠 수도 있다.
 

좀더 실제적인 예를 가지고 살펴보자 우선 클러스터드든 넌 클러스터드든 아무런 인덱스도 설정되지 않은<그림1>와 같은 테이블이 있다. 이렇게 아무런 인덱스도 설정되지 않은 테이블을 힙 테이블(Heap Table)라고 한다. 데이터는 정렬되어 있지 않고 무작위로 들어 있다. 컬럼은 번호, 이름, 주소, 나이 순으로 되어 있고, 모두 11개의 로우들로 구성되어 있는 간단한 주소 테이블이다.
 

                                                            <그림1>

이 테이블의 데이터 페이지 구성은 <그림2>과 같으며, 무작위 순으로 되어 있다. (예제를 간단히 표현하기 위해서 하나의 데이터 페이지에는 모두 4개의 로우들만 들어 갈 수 있다고 가정 하였다)

                                                             <그림2>
 
모두 3개의 데이터 페이지로 구성되어 있으며 페이지 1과2는 모두 채워져 있고 페이지 3은 여분으로 로우 하나가 더 추가 될 수 있다.(실제 상황이라면 이렇게 로우 개수를 기준으로 데이터 페이지가 채워지는 것은 아니다. 당연히 로우가 가진 실제 데이터에 맞추어서 저장 되어진다.)
 
데이터 페이지에 저장된 것은 컬럼의 정열 순서와는 아무런 상관도 없다. 순전히 데이터가 추가된 순서라고 할 수 있다. 예를 들어 번호가 1인 김수영 로우가 가장 먼저 Insert 되고, 다음에 5번인 김시원 데이터가 저장되었다.
 
이를 번호 순으로 정렬하면 <그림3>과 같은 리스트가 만들어진다. 옆에 있는 Row ID는 앞에 강좌에서 설명한 것처럼 데이터 파일, 데이터페이지 번호, 로우 번호로 구성되는 것으로써 그림에서 번호 2의 경우 ‘1-1-1’ 1번 데이터 파일에 1번 페이지의 1번 로우라는 데이터 페이지 포인터 값을 가상으로 표현한 것이다. 일단 정렬된 리스트가 있으면 이를 인덱스 페이지로 구성하는 것은 매우 간단하다.

 

넌 클러스터드 인덱스를 만드는 것은 어려운 일이 아니다. 인덱스 컬럼으로 선택된 컬럼들을 기준으로 데이터 페이지를 정렬해서 이를 B-Tree로 구성하고, 리프 레벨에서는 실제 데이터페이지로 링킹 될 수 있도록 RID를 매팅한다.


클러스터드 인덱스가 없는 넌 클러스터드 인덱스 상황에서 원하는 값을 찾을 때 어떻게 수행되는지를 알아보자. 인덱스의 구축은 최하위 레벨인 리프 레벨에서부터 루트 노드로 상향식으로 이루어졌지만, 탐색은 정반대로 루트 노드에서 리프 레벨 노드로 이루어진다. 우선 번호 15를 가지고 루트 노드의 로우들과 비교한다. 

여기서 로우 아이디를 기준으로 포인터 점프(Pointer Jump)를 한다. 포인터 점프는 데이터 페이지로 링크하는 것이다.




크리에이티브 커먼즈 라이센스
Creative Commons License 이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
트랙백 주소: http://ggoma.isblog.net/trackback_post_446.aspx

댓글을 달아 주세요