인덱스는 "색인," 즉 책의 목차와 유사한 개념입니다. 목차의 특징을 통해 인덱스의 성질을 추론할 수 있습니다.
- 빠른 검색: 목차는 원하는 정보를 빠르게 찾도록 돕습니다. 인덱스도 데이터를 빠르게 검색할 수 있도록 설계되어 있습니다.
- 참조 구조: 목차는 각 항목이 책의 특정 페이지와 연결되어 있습니다. 인덱스 역시 데이터와 해당 위치를 연결하는 참조 구조를 가지고 있습니다.
- 정렬: 목차는 항목이 순서대로 정렬되어 있어 탐색이 용이합니다. 인덱스 또한 정렬된 상태를 유지해 효율적인 검색을 지원합니다.
결론적으로, 인덱스는 정보를 빠르게 찾기 위해 설계된 구조로, 참조 구조를 통해 데이터를 연결하며 정렬된 상태를 유지한다는 특징을 가지고 있습니다.
인덱스 구조
인덱스는 정보를 빠르게 찾기 위함입니다. 그렇다면 인덱스는 어떤 구조로 구성되어있길래 정보를 빠르게 찾을 수 있을까요?
일반적으로 인덱스는 B-Tree 자료구조를 사용합니다.
B(Balanced)-Tree 자료구조는 항상 정렬된 상태를 유지하고 특정 정보를 빠르게 찾기 유리한 자료구조입니다.
B - Tree는 루트 노드, 브랜치 노드, 리프 노드로 이루어져 있으며 각 노드는 페이지로 구성이 되어있습니다.
(페이지 하나의 저장 단위로 한 페이지에 기본 16KB를 저장할 수 있습니다.)
루트 노드와 브랜치 노드의 페이지에는 각각 인덱스 키와 자식 노드의 주소가 있으며 리프 노드의 페이지만 인덱스 키와 프라이머리 키로 구성되어 있습니다. 또한, 리프 노드 페이지의 프라이머리 키를 살펴보면 데이터 파일과 대응되는 것을 알 수 있습니다. 마지막으로, 리프 노드만 살펴보면 인덱스 키가 순서대로 정렬되어있는 것을 알 수 있습니다.
처음에 목차에서 유추했듯이 인덱스는 프라이머리 키를 사용해서 데이터 파일이 위치한 주소를 알 수 있고, 인덱스 키는 순서대로 정렬이 되어 있습니다.
인덱스 키 추가 및 삭제
테이블에 레코드를 저장하거나 변경하면 인덱스 키에 추가 또는 삭제 작업이 발생합니다.
B-Tree 자료구조는 항상 정렬된 상태를 가진다는 특징이 매우 중요합니다.
새로운 인덱스를 추가할 때 적절한 위치를 탐색한 뒤 리프 노드 페이지에 저장합니다. 만약 한 페이지에 저장 가능한 데이터를 초과하면 페이지가 분리되며, 이 과정에서 변경 범위가 상위 노드로 확장될 수 있습니다.
인덱스를 삭제할 경우, 해당 인덱스가 위치한 리프 노드 페이지를 찾아 삭제 마크를 남깁니다. 삭제된 인덱스 키는 MySQL에서 자동으로 재활용됩니다.
인덱스가 변경되면 기존 인덱스는 삭제되고, 새로운 키 값에 따라 적절한 위치에 재배치됩니다. 이는 인덱스가 키 값 기준으로 정렬된 상태를 유지하기 때문에 자연스러운 과정입니다.
인덱스는 크게 프라이머리 키와 세컨더리 인덱스로 나뉩니다. 지금까지 설명한 내용은 세컨더리 인덱스에 해당합니다.
다음으로, 프라이머리 키에 대해 설명하겠습니다.
프라이머리 키
인덱스의 구조 사진에서 “데이터 파일”부분이 아래 사진에서 더 상세히 나타나 있습니다.
데이터 파일도 세컨더리 인덱스 구조와 마찬가지로 B-Tree 자료구조를 사용하고 있습니다. 다만, 세컨더리 인덱스의 리프 노드 페이지에는 인덱스 키와 프라이머리 키가 대응되었지만, 프라이머리 키의 리프 노드 페이지에는 프라이머리키와 데이터가 존재합니다.
프라이머리 키는 해당 레코드에서 다른 레코드들과 구별할 수 있는 필드 값입니다.
InnoDB에서는 기본적으로 클러스터링 인덱스를 적용하는데 클러스터링 클러스터링 인덱스는 프라이머리 키에만 적용되고, 프라이머리 키들이 그 값에 따라 정렬되어 저장되게끔 합니다.
이렇게 함으로써 프라이머리 키값을 사용해서 조회가 더 빨리 이루어질 수 있도록 합니다.
정리
옵티마이저가 세컨더리 인덱스를 사용해서 조회를 한다고 가정해보겠습니다.
세컨더리 인덱스의 루트 노드 -> 브랜치 노드 -> 리프 노드를 지나서 해당 세컨더리 인덱스와 대응되는 프라이머리 키를 만나게 됩니다.
이 프라이머리 키를 가지고 프라이머리 키의 루트 노드 -> 브랜치 노드 -> 리프 노드에 도달하면 해당 프라이머리키를 가진 레코드를 찾을 수 있게 됩니다.
지금까지 인덱스의 구조에 대해서 포스팅해보았습니다. 감사합니다!
'스터디 > MySQL' 카테고리의 다른 글
READ COMMITED와 REPEATABLE READ 비교 (0) | 2025.01.06 |
---|---|
InnoDB스토리지 엔진 수준의 락 (0) | 2025.01.06 |
MVCC(Multi Version Concurrency Control) (0) | 2024.11.27 |
MySQL이 인덱스를 이용하는 방법 (0) | 2023.09.07 |
프라이머리 키를 설정할 때 주의할 점 (0) | 2023.09.05 |