Skip to content

Clustering Index

클러스터형 인덱스는 프라이머리 키(PK) 값의 순서에 따라 테이블의 데이터가 물리적으로 정렬되어 저장되는 방식을 의미한다.

  • 변경되는 경우엔 해당 레코드의 물리적인 위치도 변경
  • 테이블 구조 자체는 일반 B-Tree와 비슷하지만, 클러스터링 인덱스의 리프노드에 레코드의 모든 컬럼이 저장

InnoDB 테이블은 반드시 클러스터형 인덱스를 가지며, 아래의 우선순위에 따라 클러스터링 키를 결정한다.

  1. 명시적으로 지정된 프라이머리 키(Primary Key)
  2. 첫 번째 NOT NULL + 유니크 인덱스(Unique Index).
  3. 내부적으로 6바이트 크기의 숨겨진 ROW_ID 컬럼 생성

보조 인덱스가 PK를 참조하는 구조

Section titled “보조 인덱스가 PK를 참조하는 구조”

InnoDB의 모든 보조 인덱스는 리프 노드에 데이터의 물리적 주소 대신 프라이머리 키 값을 저장하게 되는데, 이는 다음과 같은 이유 때문이다.

  1. 보조 인덱스가 실제 레코드 주소를 가짐
  2. 실제 레코드 주소의 PK 변경 시 레코드의 주소가 변경 필요(클러스터링 된 상태여야 하기 때문)
  3. 그때마다 해당 테이블의 모든 인덱스에 대해 변경 작업 수행 필요
  4. 오버헤드 발생

PK를 클러스터링 인덱스로 사용하는 이유

Section titled “PK를 클러스터링 인덱스로 사용하는 이유”

PK를 클러스터링 인덱스로 사용하는 이유는 읽기 성능을 향상시키기 위함이고, 그 장단점은 다음과 같다.

  • 장점
    • 프라이머리 키 기반의 범위 검색(Range Scan) 시, 데이터가 물리적으로 인접해 있어 빠른 I/O 성능 제공
    • 보조 인덱스가 프라이머리 키 값을 포함하므로, 쿼리에 필요한 모든 컬럼이 보조 인덱스와 프라이머리 키에 있다면 커버링 인덱스 사용 가능
  • 단점
    • 모든 보조 인덱스가 PK 값을 포함하므로, PK의 크기가 크면 보조 인덱스의 전체 크기도 상승
    • 데이터 삽입 시 PK 값에 따라 물리적 저장 위치가 결정되므로, 순차적이지 않은 PK 값(예: UUID)을 사용하면 페이지 분할(Page Split)이 빈번하게 발생하여 쓰기 성능이 저하 발생
    • 보조 인덱스를 통한 조회는 PK를 이용한 2차 조회로 추가적인 오버헤드 발생

Last updated:

MySQL