Skip to content
난이도 면접 빈출문제은행 6

클러스터링 인덱스 ​

클러스터링 인덱스(clustered index)는 InnoDB 테이블의 본체다. PK(Primary Key, 기본 키) 순서대로 행을 저장하는 인덱스이면서 테이블 그 자체다. 세컨더리 인덱스(secondary index)가 왜 PK 값을 들고 있는지, PK를 왜 짧고 순차적으로 잡으라고 하는지가 모두 이 구조에서 나온다.

클러스터링 = 테이블이 인덱스다 ​

클러스터링 인덱스의 리프 노드(leaf node)는 PK 순서로 정렬되고, 키뿐 아니라 행 전체를 담는다. 이 정렬은 리프를 따라 읽을 때의 논리적 인덱스 순서다. 파일 안의 모든 페이지(page)가 물리적으로 붙어 있다는 뜻은 아니다. PK가 없으면 InnoDB는 첫 번째 유니크 NOT NULL 인덱스를 기준으로 삼고, 그것도 없으면 내부에서 자동으로 매기는 6바이트짜리 숨은 행 ID를 쓴다.

정리하면 클러스터링 기준은 PK, 유니크 NOT NULL 인덱스, 숨은 키 순서로 고른다. PK를 명시하지 않고 테이블을 만들면 눈에 보이지 않는 숨은 키에 의존하게 되므로 권장하지 않는다.

세컨더리에 미치는 영향 — 두 번 읽기 ​

세컨더리 인덱스의 리프에는 행의 디스크 주소가 아니라 클러스터링 키(clustering key) 값(보통 PK 값)이 들어 있다. 그래서 쿼리에 필요한 칼럼이 세컨더리 인덱스에 다 들어 있는 커버링 인덱스(covering index)가 아니라면, 세컨더리 트리에서 PK 값을 찾은 뒤 클러스터링 트리를 차례로 한 번 더 탐색해 행을 가져온다. "두 번 읽기"는 B+Tree 탐색을 두 번 한다는 뜻이다. 실제 페이지 I/O(Input/Output, 입출력) 횟수는 캐시 상태(필요한 페이지가 이미 메모리에 올라와 있는지)와 트리 높이에 따라 달라진다.

다이어그램 로딩…

세컨더리 인덱스는 항목마다 PK 값을 들고 있다. 그래서 PK가 길면(긴 문자열이나 여러 칼럼을 묶은 복합 PK) 모든 세컨더리 인덱스가 그 길이만큼 커진다. 또 PK 값이 바뀌면 모든 세컨더리 인덱스에서 그 항목을 고쳐야 한다. PK는 짧고, 바뀌지 않고, 순차적으로 잡으라는 조언은 이 구조에서 나온다. 순차적이어야 하는 이유는 삽입 때 생기는 페이지 분할(page split) 때문이다(아래 표와 주의사항 1).

장점과 단점 ​

장점단점
PK 조회·범위가 가장 빠름PK가 크면 세컨더리 전체 비대
PK 순서 스캔이 순차 I/O(sequential I/O)랜덤 PK면 삽입이 리프 중간 분할 유발
커버링 기회가 많음PK 변경 시 연쇄 갱신

사용 시 주의사항 ​

  1. AUTO_INCREMENT 선호: 번호가 자동으로 계속 커지므로 새 행이 늘 마지막 리프에 붙는다. 그래서 페이지 분할이 적고, 최근에 쓴 마지막 페이지가 계속 메모리에 머물러 캐시 효율도 좋다.
  2. 업무 키(natural key) PK는 신중히: 업무 키는 이메일·상품 코드처럼 업무에서 원래 쓰는 값이다. 이런 값은 바뀌거나 긴 문자열인 경우가 많아, PK로 쓰면 앞에서 본 세컨더리 인덱스 비용으로 돌아온다. 그래서 의미 없는 일련번호인 대리 키(surrogate key)를 PK로 두고, 업무 키에는 유니크 인덱스(unique index)를 따로 거는 패턴이 정석이다.
  3. 복합 PK 순서: 여러 칼럼으로 된 PK는 자주 함께 조회·정렬되는 순서로 칼럼을 놓는다. 맨 왼쪽 칼럼부터 조건이 있어야 인덱스 탐색에 쓸 수 있다는 B-Tree의 좌측 접두어 규칙(leftmost prefix rule)이 PK에도 그대로 적용된다.

면접 포인트 ​

  • "클러스터링이 뭔가요?" → PK 순서 저장 + 리프에 행 전체. MyISAM(힙 구조)과 대비.
  • "PK를 짧게 잡으라는 이유는?" → 세컨더리 리프가 PK를 품어서. 두 번 읽기 그림을 그려주면 합격점.
  • "세컨더리로 조회하면 몇 번 읽어요?" → 세컨더리 1 + 클러스터링 1. 커버링이면 1번으로 끝.

관련 문서