클러스터형 인덱스
클러스터형 인덱스(Clustered Index)에서 페이지 분할이 일어나는 원리에 대해 설명하자면, 클러스터형 인덱스는 기본적으로 B+Tree 구조를 이용해 데이터를 저장하고 정렬한다. 이때 페이지 분할(Page Splitting)은 새로운 레코드를 삽입할 때 해당 페이지가 꽉 차 있으면 발생한다. 예를 들어, 하나의 페이지에 10개의 레코드를 저장할 수 있는데, 이 페이지가 가득 차 있으면 새로운 데이터를 넣을 공간이 없어 기존 데이터를 나누어 새로운 페이지를 생성해야 한다.
특히 클러스터형 인덱스는 기본 키 순서대로 데이터가 정렬되므로, 만약 UUID처럼 랜덤한 값이 기본 키라면 데이터가 중간에 삽입되어야 하는 상황이 자주 발생한다. 이 경우 중간 페이지가 가득 차면 페이지 분할이 빈번해져 성능 저하가 유발될 수 있다.
반면, AUTO_INCREMENT를 클러스터형 인덱스로 사용하면 페이지 분할이 적게 발생하는 이유는 다음과 같다. 첫째, 새 데이터가 항상 마지막 페이지에 삽입된다. AUTO_INCREMENT는 항상 증가하는 숫자를 기본 키로 사용하므로, 데이터가 B+Tree의 리프 노드 끝 부분에 연속적으로 추가된다. 중간에 데이터를 삽입할 필요가 없어 기존 페이지가 분할되지 않는다. 둘째, InnoDB는 AUTO_INCREMENT 기본 키를 사용할 때 마지막 페이지에 여유 공간을 남겨둬 분할을 사전에 방지한다. 셋째, 페이지 분할이 발생해도 순차적으로 발생해 단순히 새로운 페이지를 할당하고 연결하는 작업만 수행되므로 랜덤 키보다 훨씬 효율적이다.
UUID나 md5(), SHA-1 같은 랜덤 값이 기본 키인 경우 페이지 분할이 빈번하게 발생한다. 랜덤 키 값이 B+Tree 내 여러 위치에 삽입되면서 중간 페이지가 자주 분할되고 트리 균형 유지 비용이 증가해 성능 저하가 심각해진다.
예를 들어, 다음과 같이 UUID를 기본 키로 사용하는 테이블은 삽입 시마다 랜덤 위치에 데이터가 들어가 페이지 분할과 트리 재구성이 빈번히 일어난다.
CREATE TABLE users (
id CHAR(36) PRIMARY KEY, -- UUID (랜덤 값)
name VARCHAR(100)
) ENGINE=InnoDB;
반면, 순차적 증가 값을 사용하는 AUTO_INCREMENT 기본 키는 데이터를 항상 리프 노드 끝에 추가하므로 페이지 분할이 최소화되고 데이터가 정렬된 상태로 유지돼 삽입 성능이 향상된다.
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 순차적인 증가 값
name VARCHAR(100)
) ENGINE=InnoDB;
결론적으로, 클러스터형 인덱스에서 AUTO_INCREMENT 기본 키를 사용하는 것은 페이지 분할 문제를 줄이고 삽입 성능과 전체 인덱스 효율을 높이는 최적의 방법이다. 이렇게 하면 페이지 분할이 최소화되고, 데이터가 항상 마지막 페이지에 추가되어 성능 안정성이 확보된다. 랜덤 값 대신 순차적인 키를 사용하면 MySQL InnoDB 환경에서 훨씬 효율적인 데이터 관리를 기대할 수 있다.
'CS > 데이터베이스' 카테고리의 다른 글
| MySQL의 기본 -13 (0) | 2025.06.02 |
|---|---|
| MySQL의 기본 -11 (0) | 2025.06.02 |
| MySQL의 기본 -10 (0) | 2025.06.02 |
| MySQL의 기본 -9 (0) | 2025.06.02 |
| MySQL의 기본 -7 (0) | 2025.06.02 |