SQL/MySQL

[MySQL튜닝]Non Clustered vs. Clustered #2

스윗보스 2022. 10. 26. 17:16

이번에는 클러스터드 인덱스의 구조를 살펴볼 차례입니다. 넌클러스터드와 클러스터 인덱스의 다음 차이점을 반드시 기억하시고 읽어주시기 바랍니다.

  • 넌클러스터드 인덱스: 리프 노드에 실제 데이터를 찾아 갈 수 있는 '주소 값'이나 '키 값'이 저장된 인덱스
  • 클러스터드 인덱스: 리프 노드에 실제 '데이터'가 저장된 인덱스

 

2. Clustered Index

T_ORD_BIG의 클러스터드 인덱스는 Primary 인덱스입니다.
앞에 글에서도 'SHOW INDEX FROM T_ORD_BIG' 을 실행했을 때, 'Key_name'이 'Primary'로 되어 있는 인덱스가 바로 클러스터드 인덱스라고 설명했습니다.

 

여기서 잠깐, MySQL에서는 인덱스라는 용어를 Key라는 용어와 혼용해서 사용합니다.

그러므로 'SHOW INDEX FROM'을 실행하면 인덱스의 이름 항목이 'Index_name'이 아닌 'Key_name'으로 나옵니다.

 

T_ORD_BIG의 클러스터드(Primary) 인덱스는 PK(Primary Key) 컬럼인 ORD_SEQ로 구성되어 있습니다.

MySQL의 InnoDB 스토리지 엔진에서, 테이블의 PK 컬럼은 무조건 클러스터드 인덱스로 만들어집니다.
다시 말해, '테이블 생성 = 클러스터드 인덱스 생성'이 됩니다. 우리는 테이블을 만들지만, 테이블의 데이터는 클러스터드 인덱스 구조로 관리가 되는겁니다.
아무리, 클러스터드 구조로 테이블을 만들기 싫어도 방법이 없습니다.

클러스터드 인덱스를 피하기 위해 PK를 설정하지 않아도, 내부적으로 6 byte의 Hidden 컬럼을 만들어 PK를 구성한다고 합니다.

(구글링을 해보면, 이와 같은 이야기가 나오는데, MySQL 공식 레퍼런스에서는 이와 같은 부분을 찾을수가 없네요. 혹시 MySQL 레퍼런스에서 보신분 있으면 알려주세요!^^)

 

T_ORD_BIG의 클러스터드 인덱스를 그려보면 아래 그림과 같습니다. 처음에 이야기했듯이, 인덱스의 리프 노드에는 실제 데이터가 저장되어 있는 것을 알 수 있습니다.

 

클러스터드 인덱스의 리프 노드에는 실제 데이터가 저장되어 있으므로, 테이블 별로 하나만 만들 수 있습니다. 넌 클러스터드는 하나의 테이블에 여러개 만들 수 있지만, 클러스터드는 무조건 하나만 만들 수 있으므로 클러스터할 컬럼 선택에 신중한 선택이 필요합니다. 하지만 MySQL은 무조건 PK 컬럼에 클러스터드를 설정하므로 선택의 폭이 제한적입니다.

 

클러스터드 인덱스와 같은 개념으로 오라클에는 IOT가 있습니다. 오라클의 IOT는 선택이라면, MySQL의 클러스터드 인덱스는 강제적입니다.

MS-SQL Server에도 클러스터드 인데스가 있습니다. MS-SQL Server에서 클러스터드 인덱스는 PK 컬럼이 아닌 곳에도 설정할 수 있습니다. 반면에 MySQL에서는 무조건 PK 컬럼에만 클러스터드 인덱스가 설정이 됩니다.

이와 같은 특징을 잘 이해하고 MySQL의 테이블을 설계할 필요가 있습니다.