[Database] 클러스터링 인덱스와 논 클러스터링 인덱스
0. 들어가기전에
자주 나오는 인덱스 개념인 클러스터링 인덱스와 논 클러스터링 인덱스에 대해서 알아보았습니다.
1. 클러스터링 인덱스
MySQL InnoDB에서는 클러스터링 인덱스를 항상 사용한다.보통 테이블의 PK에 적용이 되는 인덱스이며, PK가 없으면 not null + unique
한 컬럼에 사용이 되며, 이마저도 없으면 임의의 값으로 MySQL이 만들어서 사용한다. 그래서 항상 InnoDB를 사용하는 테이블에는 클러스터링 인덱스가 적용되어 있다고 할 수 있다.
그렇다면 왜 이런 방식을 사용하는 걸까? 그 이유는 검색 속도가 빠르기 때문이다. 클러스터링 인덱스는 테이블을 물리적으로 정렬을 한 인덱스이다. 즉, PK가 있다면 PK 기준으로 데이터들이 실제로 정렬이 되어 있어서 범위 탐색에 좋다. 추가로 디스크 I/O 측면에서 보면 근처에 있는 데이터를 같은 페이지로 들고 올 수 있어서 순차 탐색이 되어 속도가 향상된다.
클러스터링 인덱스도 단점이 존재하는데, 인덱스의 값(앞으로 PK라고 가정) PK가 변경되면 데이터를 다시 정렬해야 하기 때문에 상대적으로 느린 동작이 된다. 또한 클러스터링 인덱스는 테이블당 1개만 설정이 가능하다는 특징이 있다.
2. 논클러스터링 인덱스
논클러스터링 인덱스는 세컨더리 인덱스라고도 불린다. 이 인덱스는 사용자가 직접 추가한 인덱스이다. 그러므로 PK로 설정된 인덱스를 제외하고 추가한 인덱스는 모두 논클러스터링 인덱스가 된다. 논클러스터링 인덱스의 특징은 리프노드에서 데이터가 존재하는 게 아니라 데이터의 위치를 저장한다는 점이 다르다. 즉, 리프노드에서 인덱스로 설정한 컬럼은 정렬이 되어있지만 실제 데이터의 위치만 알고 있으므로 한 번 더 탐색을 해 데이터를 찾아야 한다.
3. 클러스터링 인덱스 + 논클러스터링 인덱스
실제 DB를 보면 클러스터링 인덱스는 항상 테이블에 설정이 되므로 클러스터링 인덱스와 논클러스터링 인덱스가 혼합된 형태라고 볼 수 있다. 이 경우에는 논클러스터링 인덱스가 살짝 다르게 구현된다.
앞서 논클러스터링 인덱스는 리프 노드에 실제 데이터의 위치를 저장한다고 말했었다. 하지만 클러스터링 인덱스가 같은 테이블에 존재하는 경우, 리프 노드에서 PK 값을 알고 있게 된다.
이때 논클러스터링 인덱스를 통해 탐색하게 되면 탐색을 하게 되면, 논클러스터링 인덱스를 한 번 탐색하고 난 뒤 PK 값을 찾고, 찾은 PK 값으로 클러스터링 인덱스를 찾게 된다. 이렇게 만든 이유는 데이터의 변경 때문이다. 만약 논클러스터링 인덱스가 데이터의 위치를 알고 있는 상태에서, 테이블 중간에 데이터를 삽입하면 어떻게 될까? 삽입된 데이터 뒤에 있는 데이터들은 모두 한 칸씩 밀릴 것이고 이에 따라 논클러스터링 인덱스도 모두 변경될 것이다. 만약 PK를 들고 있었다면, 일반적으로 PK는 auto increment 값을 사용하므로 변경 영향이 적을 것이다.
이 방식의 유의할 점은 PK 클러스터링 인덱스의 크기에 따라 데이터베이스에서 인덱스의 크기가 달라진다는 점이 있다. 왜냐하면 모든 논클러스터링 인덱스는 클러스터링 인덱스인 PK 값을 가지고 있으므로 PK의 용량에 따라서 저장되는 데이터 양이 기하 급수적으로 늘어나기 때문이다. 따라서 이 점을 유의해서 사용을 해야한다.
※ 참고
'CS > [DATABASE]' 카테고리의 다른 글
[Database] 인덱스 (1) | 2023.09.10 |
---|---|
[DataBase] Flyway 톺아보기 (0) | 2023.07.02 |
[데이터베이스] 인덱스 (0) | 2022.05.23 |
Chapter14 트랜잭션 (0) | 2022.02.01 |
Chapter12 정규화 (0) | 2022.01.27 |