1) 클러스터링 인덱스란?
- 클러스터링이란 여러 개를 하나로 묶는다는 의미로 주로 사용되는데,
지금 설명하고자 하는 인덱스의 클러스터링도 그 의미를 크게 벗어나지 않는다.
- MySQL 서버에서 클러스터링은 테이블의 레코드를 비슷한 것(프라이머리 키를 기준으로) 묶어서
저장하는 형태로 구현되는데, 이는 주로 비슷한 값들을 동시에 조회하는 경우가 많다는 점에서
착안한 것이다.
- MySQL에서 클러스터링 인덱스는 InnoDB 스토리지 엔진에서만 지원하며,
나머지 스토리지 엔진에서는 지원되지 않는다
2) 클러스터링 인덱스 특징
- 클러스터링 인덱스는 테이블의 프라이머리 키에 대해서만 적용되는 내용이다.
즉, 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터링 인덱스라고 표현한다.
- 클러스터링 인덱스는 프라이머리 키 값에 의해 레코드의 저장 위치가 결정되므로
사실 인덱스 알고리즘이라기보다 테이블 레코드의 저장 방식이라고 볼 수 있다.
그래서 "클러스터링 인덱스"와 "클러스터링 테이블"은 동의어로 사용되기도 한다.
- 또한 클러스터링의 기준이 되는 프라이머리 키는 클러스터링 키라고도 표현한다.
일반적으로 InnoDB와 같이 항상 클러스터링 인덱스로 저장되는 테이블은 프라이머리 키 기반의 검색이 매우 빠르며,
대신 레코드의 저장이나 프라이머리 키의 변경이 상대적으로 느리다.
- 아래 그림 8.25은 클러스터링 테이블의 특성을 이해하기 쉽도록 클러스터링 테이블의 구조를 그림으로 표현한 것이다.
- 위의 그림의 클러스터링 인덱스 구조를 보면 클러스터링 테이블의 구조 자체는 일반 B-Tree와 비슷하다.
하지만 세컨더리 인덱스를 위한 B-Tree의 리프 노드와는 달리
위 그림의 클러스터링 인덱스의 리프 노드에는 레코드의 모든 칼럼이 같이 저장돼 있음을 알 수 있다.
- 즉, 클러스터링 테이블은 그 자체가 하나의 거대한 인덱스 구조로 관리되는 것이다.
3) 프라이머리 키(=클러스터링 키) 변경해보기
- 위 그림의 클러스터링 테이블에서 다음 쿼리와 같이 프라이머리 키(employees 테이블의 emp_no 칼럼)를
변경하는 문장이 실행되면 클러스터링 테이블의 데이터 레코드에는 어떤 변화가 일어날까?
mysql> UPDATE tb_test SET emp_no=100002 WHERE emp_no=100007;
- 위 그림에서는 emp_no가 100007인 레코드는 3번 페이지에 저장돼 있음을 확인할 수 있다.
하지만 emp_no가 100002로 변경되면 2번 페이지로 이동한다.
- 실제로 프라이머리 키의 값이 변경되는 경우는 거의 없을 것이다.
여기서는 클러스터링 테이블에서 프라이머리 키 값의 중요성을 다시 한 번 강조하고,
클러스터링 테이블의 작동 방식을 설명하기 위해 프라이머리 키 값의 변경 과정을 한 번 살펴본 것이다.
4) 프라이머리 키가 없는 경우
- 그러면 프라이머리 키가 없는 InnoDB 테이블은 어떻게 클러스터링 테이블로 구성될까?
프라이머리 키가 없는 경우에는 InnoDB 스토리지 엔진이
다음 우선순위대로 프라이머리 키를 대체할 칼럼을 선택한다.
1. 프라이머리 키가 있으면 기본적으로 프라이머리 키를 클러스터링 키로 선택
2. NOT NULL 옵션의 유니크 인덱스(UNIQUE INDEX) 중에서 첫 번째 인덱스를 클러스터링 키로 선택
3. 자동으로 유니크한 값을 가지도록 증가되는 칼럼을 내부적으로 추가한 후, 클러스터링 키로 선택
- InnoDB 스토리지 엔진이 적절한 클러스터링 키 후보를 찾지 못하는 경우
InnoDB 스토리지 엔진이 내부적으로 레코드의 일련번호 칼럼을 생성한다.
이렇게 자동으로 추가된 프라이머리 키(일련번호 칼럼)는 사용자에게 노출되지 않으며,
쿼리 문장에 명시적으로 사용할 수 없다.
- 즉, 프라이머리 키나 유니크 인덱스가 전혀 없는 InnoDB 테이블에서는
아무 의미 없는 숫자 값으로 클러스터링되는 것이며,
이것은 우리에게 아무런 혜택을 주지 않는다.
- InnoDB 테이블에서 클러스터링 인덱스는 테이블당 단 하나만 가질 수 있는
엄청난 혜택이므로 가능하다면 프라이머리 키를 명시적으로 생성하자.
'Real MySQL 1권' 카테고리의 다른 글
[Real MySQL 1권] InnoDB 버퍼 (0) | 2024.12.16 |
---|---|
[Real MySQL 1권] MVCC (0) | 2024.12.12 |
[Real MySQL 1권] 인덱스와 잠금 (0) | 2024.06.28 |
[Real Mysql 1권] 슬로우 쿼리 로그 (0) | 2024.06.28 |
[Real MySQL 1권] 옵티마이저 (0) | 2024.06.26 |