본문 바로가기
Database

[DataBase / SQL] 클러스터드 인덱스 (Clustered Index), 넌 클러스터드 인덱스 (Non Clustered Index)란

by nam_ji 2024. 2. 14.

클러스터 인덱스와 넌 클러스터 인덱스 알아보기

1) 인덱스 (Index)

  • 인덱스는 데이터 레코드를 빠르게 접근하기 위해서 <키, 포인터> 쌍으로 구성되는 데이터 구조입니다. 테이블에 데이터가 저장되는데, 특정한 PK 값을 가지는 데이터를 찾기 위해서 매번 접근하는 것은 비효율적입니다. PK 값과 해당하는 데이터 row의 주소를 자료구조로 묶어서 저장하는 것이 인덱스입니다.
  • 따라서, 인덱스는 DB의 테이블에 데이터가 많을 때, 검색 속도를 향상시켜 주기 위해 사용하는 객체입니다. 컬럼을 정렬한 후에 데이터를 빠르게 찾을 수 있ㄷ로고 도와주는 역할을 합니다.
  • 즉, 인덱스의 가장 큰 목적은 대용량 데이터 조회 시 SELECT문의 조회 속도를 향상시키는 것입니다.
    인덱스로 설정되지 않은 컬럼의 조회는 Full Scan (Table Scan) 수행하기 때문에 속도 저하를 가져옵니
  • 하지만 인덱스를 생성하면 무조건 데이터를 빠르게 검색할 수 있는건 아닙니다.
    그래서 인덱스를 무작정 생성한다고 좋은 방법이 될 수 있는거 아닙니다.
  • 인덱스를 생성하면 인덱스를 위한 디스크 공간이 필요하고, 인덱스를 가진 테이블에 DML 작업을 할 경우 더 많은 비용과 시간이 필요합니다.
  • 때문에 인덱스 생성 시 해당 테이블의 의도를 정확하게 파악한 후 상황에 맞게 적절한 컬럼으로 Clustered Index와 Non Clustered Index를 구성해야 합니다.
    • DML (Data Manipulation Language)
      - > 데이터를 조작하는 명령어 : SELECT, INSERT, UPDATE, DELETE
  • 책으로 비유를 하면
    • 클러스터 인덱스 : 페이지를 알기 때문에 바로 그 페이지를 펴는 것입니다.
    • 넌 클러스터 인덱스 : 목차에서 찾고자 하는 내용의 페이지를 찾고 그 페이지로 이동하는 것입니다.
    • 테이블 스캔 : 처음부터 한 장씩 넘기면서 내용을 찾는 것입니다.

2) 클러스터 인덱스 (Clustered Index)

  • Clustered Index를 구성하기 위해서 행 데이터를 해당 열로 정렬한후, 루트 페이지를 만들게 됩니다. (물리적으로 행을 재배열)
  • Clustered Index는 트리로 저장되어, Root 페이지와 Leaf 페이지로 구성됩니다.
    또한 Root 페이지는 Leaf 페이지의 주소로 구성하고, Leaf 페이지는 실제 데이터 페이지로 구성됩니다.
    따로 추가적인 저장소에 인덱스 페이지를 만들지 않습니다.
  • 테이블당 단 하나의 Clustered Index만 존재할 수 있습니다.
  • 클러스터 인덱스 순서로 레코드들이 하드디스크에 저장됩니다. 클러스터 인덱스를 다로 지정하지 않으면, 기본 키 (Primary Key, PK)를 지정하면 그 칼럼은 자동으로 Clustered Index가 만들어집니다.
    -> 만약 Clustered Index를 따로 지정하고 싶으면, 설정을 통해 테이블 내에서 원하는 컬럼으로 Clustered Index로 생성할 수 있습니다.
  • 데이터 입력, 수정, 삭제 시 항상 정렬 상태를 유지합니다.
  • Clustered Index는 물리적으로 정렬되어 있어 검색 속도가 Non-Clustered Index 보다 더 빠릅니다. 
    하지만 데이터의 입력, 수정, 삭제는 느립니다.

2-1) 사용하는 경우

  • 테이블 데이터가 자주 업데이트 되지 않는 경우 사용합니다.
  • MAX, MIN, COUNT 등의 쿼리로 범위 또는 GROUP BY 등의 조회를 하는 경우 사용합니다.
  • 항상 정렬 된 방식으로 데이터를 반환해야 하는 경우 사용합니다.
    • 테이블은 정렬되어 있기 때문에 ORDER BY 절을 활용해 모든 테이블 데이터를 스캔하지 않고 원하는 데이터를 조회할 수 있습니다.
  • 일기 작업이 월등히 많은 경우, 이때 매우 빠릅니다.

2-2) 단점

  • 리프 페이지가 모두 채워져 있는데 새로운 데이터가 추가될 때 페이지 분할이 일어납니다.
    -> 인덱스는 Balancing - Tree 구조이기 때문에 기본적으로 모두 같은 크기의 페이지를 유지합니다. 그래서 새로운 데이터가 추가되면 새로운 데이터가 추가 될 테이블의 기존 데이터 절반이 새로운 페이지로 이동한 후 새로운 행이 추가됩니다.
    이와 같이, 인덱스를 생성 / 수정 / 삭제할 때 페이지 분할이 일어나며 데이터 페이지 전체를 다시 정렬해야 하기 때문에 느려집니다.
  • 항상 순서를 유지해야 합니다.

3) 넌클러스터 인덱스 (Non Clustered Index)

  • 레코드의 원본은 정렬되지 않고, 인덱스 페이지만 정렬됩니다. 즉, Non-Clustered Index는 데이터 페이지를 건드리지 않고, 별도의 장소에 인덱스 페이지를 생성합니다.
  • 인덱스 페이지의 리프 페이지에 Index로 구성한 열을 정렬한 후 위치 포인터 (RID)를 생성합니다. 즉, Non-Clustered Index의 인덱스 페이지 (리프 페이지)는 키값과 데이터가 위치하는 포인터 (RID)로 구성됩니다.
    • 포인터 (RID) : '파일 그룹 번호 + 데이터 페이지 번호 + 페이지 내 로우 번호'로 구성되는 포인팅 정보
  • 인덱스를 생성할 때 데이터 페이지는 그냥 둔 상태에서 별도의 인덱스 페이지를 따로 만들기 때문에 용량을 더 차지합니다.
  • 테이블당 약 240개의 Non-Clustered Index를 만들 수 있습니다.
  • 클러스터보다 검색 속도는 느리지만 데이터 입력, 수정, 삭제는 더 빠릅니다.
    -> 클러스터 인덱스보다 페이지 분할이 적게 일어납니다.
  • 데이터 검색 순서 : 루트페이지 > 리프페이지 > 데이터 페이지 (Heap Page)
  • 리프페이지가 모두 채워져 있어도 페이지 분할은 일어나지 않습니다.

3-1) 사용하는 경우

  • WHERE 절이나 JOIN 절과 같이 조건문을 활용하여 테이블을 필터링 하고자 할 경우 사용합니다.
  • 데이터가 자주 업데이트 될 경우 사용합니다.
  • 특정 컬럼이 쿼리에서 자주 사용될 경우 사용합니다.

3-2) 단점

  • 클러스터 인덱스는 테이블 정렬만 하면 되니 추가적인 저장공간이 필요없지만, 넌클러슽 인덱스는 인덱스 페이지만을 위한 추가 저장공간이 필요합니다.
    -> 데이터 삽입 시 넌클러스터 인덱스는 별도의 공간에 인덱스를 생성해야 하기 때문에 추가작업이 필요합니다.
  • 넌클러스터 인덱스는 데이터 접근 속도가 클러스터 인덱스보다 상대적으로 느립니다.
  • 인덱스 조회 시 비용이 많이 발생합니다. (거쳐야 하는 단계가 많습니다.)
    -> 검색하고자 하는 데이터의 키 값을 루트 페이지에서 비교하여 리프 페이지 변호를 찾고, 리프 페이지에서 RID 정보로 실제 데이터의 위치로 이동합니다.
  • 클러스터 인덱스의 변경이 발생할 때 그에 상응하는 업데이트가 발생합니다.

클러스터 인덱스와 넌클러스터 인덱스 간단 비교

Clustered Index Non Clustered Index
리프 테이블 자체가 인덱스 테이블과 별개로 인덱스 존재
실제 데이터 정렬 실제 데이터 정렬 X
테이블 당 1개만 존재 테이블 당 여러 개 존재 가능
검색 속도에 우위 변경속도에 우위