"인덱스를 걸었는데도 왜 어떤 건 빠르고 어떤 건 느릴까?" 인덱스를 배우다 보면 클러스터드와 논클러스터드라는 두 단어에서 막힙니다. 둘의 차이는 한 문장으로 요약됩니다. 클러스터드 인덱스는 데이터 자체를 정렬해 저장하고, 논클러스터드 인덱스는 데이터 위치를 가리키는 별도 목록을 만든다. 책으로 비유하면 클러스터드는 페이지 번호 순서대로 인쇄된 책 본문이고, 논클러스터드는 책 뒤의 색인(찾아보기)입니다.
두 인덱스 한눈에 비교
| 구분 | 클러스터드 인덱스 | 논클러스터드 인덱스 |
|---|---|---|
| 데이터 저장 | 인덱스 순서대로 실제 행을 정렬 | 행은 그대로, 위치 포인터만 정렬 |
| 테이블당 개수 | 1개만 가능 | 여러 개 가능 |
| 검색 방식 | 인덱스 = 데이터, 바로 도달 | 인덱스 찾고 다시 데이터로 점프 |
| 비유 | 사전 본문(가나다순 인쇄) | 책 뒤 찾아보기 색인 |
핵심은 "데이터가 한 가지 순서로만 물리적으로 정렬될 수 있다"는 점입니다. 그래서 정렬 기준이 되는 클러스터드 인덱스는 테이블에 단 하나뿐이고, 보통 기본 키(PK)가 그 역할을 맡습니다.
검색 경로가 어떻게 다른가
members 테이블에서 id가 클러스터드(PK), email이 논클러스터드라고 해봅시다.
CREATE TABLE members (
id BIGINT PRIMARY KEY, -- 클러스터드 인덱스
email VARCHAR(200),
name VARCHAR(50)
);
CREATE INDEX idx_email ON members(email); -- 논클러스터드
id로 찾으면 데이터가 id 순서로 이미 정렬돼 있어 한 번에 도달합니다.
SELECT * FROM members WHERE id = 1024;
반면 email로 찾으면 두 단계입니다. 먼저 idx_email 색인에서 해당 email의 위치(PK 값)를 찾고, 그 PK로 실제 행을 다시 찾아갑니다. 이 추가 점프를 "키 조회(key lookup)"라고 부르며, 논클러스터드가 한 단계 더 도는 이유입니다.
SELECT * FROM members WHERE email = 'kim@example.com';
선택 기준
| 상황 | 권장 |
|---|---|
| 범위 조회가 잦은 컬럼(날짜, 순번) | 클러스터드가 유리 (정렬돼 연속 읽기) |
| 정확히 한 건만 자주 찾는 보조 컬럼 | 논클러스터드 |
| 자주 바뀌는 값 | 클러스터드 키로는 부적합 (재정렬 비용) |
클러스터드 키는 한 번 정하면 데이터 물리 순서를 좌우하므로, 값이 거의 안 바뀌고 단조 증가하는 컬럼(예: auto increment id)이 적합합니다. 무작위 UUID를 클러스터드 키로 쓰면 삽입할 때마다 중간에 끼워넣어 페이지가 쪼개지는 문제가 생깁니다.
요점 정리
- 클러스터드는 데이터 자체를 정렬 저장 → 테이블당 1개, 정렬 기준 검색이 가장 빠름.
- 논클러스터드는 위치를 가리키는 색인 → 여러 개 가능, 키 조회로 한 단계 더 점프.
- 클러스터드 키는 단조 증가하고 잘 안 바뀌는 컬럼이 적합하다.
EXPLAIN으로 키 조회가 실제로 일어나는지 직접 보고, 인덱스 설계로 쿼리 속도가 어떻게 달라지는지 확인하는 실습은 데이터베이스 트랙에서 회원가입 없이 무료로 할 수 있습니다.