Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

영우

클러스터링 인덱스의 사실과 오해 본문

CS/데이터베이스

클러스터링 인덱스의 사실과 오해

duddn 2024. 2. 15. 19:48

클러스터링 인덱스가 막연히 PK에 따라 정렬되어 있다는것 정도만 알고있고, 동작에 대해 의문점이 많은 상태였습니다.

제가 오해 && 다시 이해한 내용들을 이 글을 통해 공유하려합니다.

 

클러스터링 인덱스란 무슨뜻 일까요?

클러스터는 군집 이라는 의미로 포도송이 처럼 비슷한 개체끼리 다닥다닥 붙어있다는 의미입니다.

그렇다면 인덱스는 무슨뜻 일까요? 인덱스는 책 뒷부분에 있는 색인으로 원하는 데이터를 빠르게 찾기위한 도구입니다.

결국 클러스터링 인덱스란 인덱스들이 다닥다닥 붙어있다. 즉 비슷한 인덱스끼리 모여있다는 의미입니다.

InnoDB는 클러스터링 인덱스이므로 비슷한 인덱스들이 테이블에 물리적으로 모이고 정렬되어 저장됩니다. 이때 비슷한 인덱스로 PK를 클러스터해 저장하기 때문에 PK를 클러스터링 키라고도 합니다.

다시 말해, PK에 의해 레코드의 물리적인 저장위치가 결정되게 됩니다. 이때 데이터를 B트리 자료구조로 PK값과 자식노드의 페이지번호가 매핑되게 저장합니다. 그리고 트리의 리프노드에는 실제 데이터가 위치하게 됩니다.

 

  • Q. 클러스터링 인덱스라는 말이 이상합니다. 인덱스들이 cluster한게 아니라, cluster된거 아닐까요?
  • A. 맞습니다. 영어로 clustered index입니다. 클러스터된 인덱스라고 이해하는게 편안합니다.

 

  • Q. PK없이 테이블을 생성하면 어떻게 될까요?
  • A. NOT NULL의 유니크 인덱스 중 첫번째 인덱스를 클러스터링 키로 선택합니다. 없다면, 내부적으로 auto-increment 컬럼 추가후 클러스터링 키로 선택합니다.

 

  • Q. 물리적으로 정렬되어 저장된다면 데이터가 삭제되면 어떡할까요? 빈 공간을 채우기 위해 뒤의 모든 데이터를 당겨와야할까요? 또 꽉찬 테이블에 데이터가 삽입된다면 어떻게되나요? 공간을 만들기 위해 뒤의 데이터를 모두 한칸씩 밀어야 할까요?
  • A. 데이터 천만개가 있다면, 모든 데이터가 하나의공간에 빼곡하게 존재하는게 아니라, 페이지단위로 나누어서 저장됩니다. 만약 가득찬 페이지에 삽입이 이루어진다면, 전체를 변경하는 것이 아니라, 페이지 하나를 분할하면 되는것입니다. 데이터가 삭제되면 빈 공간으로 두었다가, 페이지의 빈공간이 너무 많아지면 인접한 페이지와 합쳐 효율적으로 공간을 관리하게 됩니다.

 

  • Q. 클러스터링 인덱스에서 모든 데이터가 물리적으로 정렬된것이 아니라, 페이지내의 데이터가 PK를 기준으로 물리적으로 정렬된건가요?
  • A. 훌륭합니다! 페이지내에 데이터가 물리적으로 정렬된것이고, 페이지들은 정렬되어있지 않습니다.

 

  • Q. 클러스터링 인덱스는 B-Tree에서 PK와 페이지번호가 매핑되나요? 그렇다면 실제 데이터는 어떻게 찾나요?
  • A. 네. PK와 페이지번호가 매핑됩니다. 페이지 내에서 PK를 찾는 방법은 페이지 내에 레코드의 수와 같은 메타데이터를 이용해 정렬되어있다는 특성에 기반한 이진탐색을 통해 PK를 검색합니다.

비 클러스터링 인덱스?

데이터를 물리적으로 정렬해 저장하지 않고 임의의 빈 공간 혹은 데이터 끝 부분에 저장합니다. 그리고 그 주소를 B-tree에 인덱스와 매핑하게 됩니다.

비 클러스터링 인덱스와 클러스터링 인덱스를 비교해주세요.

  • 클러스터링 인덱스는 비 클러스터링 인덱스보다 PK에 대해 읽기가 쉽고, 쓰기가 어렵습니다.
  • 비 클러스터링 인덱스는 모든 인덱스에 B-tree에 PK값과 데이터의 물리적인 위치를 매핑하는 반면, 클러스터링 인덱스는 세컨더리 인덱스가 물리적인 위치가 아닌 PK의 값을 매핑합니다.

왜 클러스터링 인덱스는 PK에 대한 읽기가 유리한가요?

키 값이 물리적으로 정렬되어있기 때문에 PK의 범위 검색에 매우 유리합니다. 시작하는 값을 검색한 후 추가적인 검색없이 순차적으로 디스크를 읽으면 되기 때문입니다. 또한 데이터가 몰려있으므로 디스크의 페이지도 더 적게 IO할 수 있습니다.

PK단일 조회도 유리한 측면이 있습니다. 클러스터링 인덱스는 B트리의 리프노드에 실제 데이터가 있는 반면, 비 클러스터링 인덱스는 리프노드에 데이터의 물리적인 주소가 있습니다. 물리적인 주소의 페이지를 한번더 읽어야 하기 때문에 클러스터링 인덱스는 디스크 IO를 한번 줄일수있습니다.

왜 클러스터링 인덱스는 쓰기가 어렵나요?

클러스터링 인덱스는 데이터를 삽입할때 PK의 순서에 유의해 삽입해야 합니다. PK에 맞는 위치에 찾아가 데이터를 써야하고, 페이지가 꽉차 데이터를 바로 작성하기 어려운 경우에는 페이지 분할을 해야하는 어려움이 있습니다. 또한 데이터를 삭제할때는 빈공간이 생겨 데이터 단편화를 유발해 저장공간이 낭비될 수 있습니다.

 

출처

  • RealMySQL8.0