클러스터드/넌클러스터드 인덱스의 개념이 생각보다 복잡해서 따로 포스팅에 정리하기로 했다.

이 글에서 말하는 모든 인덱스 구조는 B*tree 구조를 바탕으로 하고 있다. 즉 각 노드들이 트리모양을 이루며 루트 노드부터 리프 노드까지 서로 포인터를 통해 연결되어 있는 구조이다.



1. 클러스터드 인덱스 (Clustered Index)

우선 클러스터드 인덱스의 생성 방법을 동영상을 통해 익혀보자.

동영상에 예시로 등장하는 테이블의 데이터는 정렬되어 있지 않은 상태이다. 이런 상태의 테이블을 힙(Heap)이라고 일컫는다. 그 상태에서 '클러스터드 인덱스 (Clustered Index)'를 생성할 경우, 테이블의 데이터 자체가 물리적으로 재배열되어 순서대로 정렬된다. 테이블 자체가 클러스터드 인덱스의 리프 노드(leaf node)로서 기능하기 때문이다. 

인덱스가 테이블 데이터 자체를 포함하는 이런 형식은 흔히 전화번호부와 비교된다. 전화번호부 또한 번호목록이라는 데이터 자체가 인덱스 기능을 하고 있다. 전화번호부가 단순한 번호목록과 구별되는 부분은 각 페이지의 첫 상호명, ㄱ으로 시작하는 첫 상호명 등 일부 데이터를 한 눈에 알아볼 수 있도록 표기함으로서 데이터의 큰 경향을 쉽게 파악해서 원하는 데이터가 있는 부분으로 이동할 수 있도록 한 부분이다. 클러스터드 인덱스도 마찬가지이다. 


(출처:https://technet.microsoft.com/en-us/library/ms177443(v=sql.105).aspx)

위 그림에서 리프 노드들은 테이블의 데이터 자체이고, 그를 큰 단위로 분류한 중간 단계(Internediate Level)와 하나의 페이지 안에 모아놓은 루트 노드 (Root Node)로 연결된다. 전화번호부의 비유에서 ㄱ각 페이지의 첫 상호를 크게 표시한 것은 중간 단계에, ㄱ부터 ㅎ까지의 자음을 포함한 첫 상호명들을 모아놓은 것은 루트 노드에 비유될 수 있을 것이다. 

테이블 자체가 물리적으로 재배열되어 인덱스 구조에 포함되므로, 클러스터드 인덱스는 각 테이블 당 1개씩만 생성될 수 있다.




2. 넌클러스터드 인덱스 (Non-Clustered Index)

클러스터드 인덱스와 달리 넌클러스터드 인덱스의 필요성과 생성 과정은 직관적으로 이해하기 힘들다. 우선 아래의 동영상을 통해 사용 사례를 살펴보자.


넌클러스터드 인덱스는 원 테이블을 재배열하지 않는다. 무작위, 혹은 클러스터드 인덱스대로 배열되어있는 테이블을 단지 가리킬 뿐이다. 위 동영상의 경우 원 테이블은 ID 순서대로 배열되어 있으나, 이에 대해 이름 순서대로 배열된 인덱스를 따로 생성해서, 그 인덱스가 원 테이블을 가리키도록 하고 있다. 


(출처: https://technet.microsoft.com/en-us/library/ms177484(v=sql.105).aspx)

즉 클러스터드 인덱스에서는 데이터 페이지 자체를 리프 노드로 사용하는 반면, 넌클러스터드 인덱스는 원하는 순서대로 정렬된 리프 노드를 새로 만들어 그 리프노드들이 데이터 페이지를 가리키도록 하는 것이다. 따라서 원 테이블에는 영향이 가지 않으므로 얼마든지 새로 만들 수 있으며, 테이블에서 일부 데이터만을 따로 인덱스로 만드는 일도 가능하다. 

넌클러스터드 인덱스를 생성하면 이처럼 한 테이블에 대해 다양한 인덱스를 만들 수 있으나, 그림에서도 나타나다시피 저장 공간이 훨씬 많이 소요되고 구조 또한 복잡하다는 단점이 있다. 




AND