한 줄 정의
인덱스는 데이터를 정렬해 보관 함으로써 검색 비용을 낮추는 자료구조이며, MySQL의 모든 성능 튜닝은 결국 “어떤 인덱스를, 어떻게 타게 만들 것인가”의 문제로 귀결됩니다.
쉽게 말하면
인덱스는 책 뒷면의 색인 과 정확히 같습니다.
- 색인이 없다면 원하는 단어를 찾기 위해 첫 페이지부터 끝까지 읽어야 합니다 (풀 스캔)
- 색인이 있으면 단어의 첫 글자로 대략적인 페이지를 찾고, 그 근처만 뒤지면 됩니다 (인덱스 레인지 스캔)
- 다만 색인을 만들려면 책 내용을 미리 정리해두는 비용 이 들고, 책이 개정될 때마다 색인도 갱신해야 합니다 (INSERT/UPDATE/DELETE 비용)
인덱스는 읽기를 빠르게 하는 대신 쓰기를 느리게 하는 트레이드오프입니다.
왜 중요한가?
MySQL에서 인덱스는 단순히 “조회 속도”만의 문제가 아닙니다.
- 잠금 범위의 결정자 : InnoDB는 레코드가 아니라 인덱스를 잠급니다. 인덱스가 없으면 테이블 전체가 잠깁니다 (Ch05-3 InnoDB 스토리지 엔진 잠금)
- 옵티마이저의 판단 근거 : 옵티마이저는 인덱스 통계를 기반으로 실행 계획을 결정합니다. 통계가 틀리면 잘못된 인덱스를 타거나 풀 스캔을 선택합니다
- 스토리지 엔진의 기반 : InnoDB의 PK는 클러스터링 인덱스 그 자체이며, 테이블의 물리적 저장 구조를 결정합니다
“인덱스를 안다”는 것은 MySQL의 모든 동작을 이해할 수 있는 공통 기반 지식 을 갖추는 것입니다.
핵심 내용
8.1 디스크 읽기 방식
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-1 디스크 읽기 방식 | HDD vs SSD, 랜덤 I/O vs 순차 I/O, 인덱스가 필요한 근본 이유 |
인덱스가 필요한 이유는 결국 랜덤 I/O를 줄이기 위함 입니다. 디스크의 물리적 특성을 이해해야 왜 인덱스가 성능을 좌우하는지 알 수 있습니다.
8.2 인덱스란 무엇인가
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-2 인덱스란 무엇인가 | 인덱스의 정의, 분류 기준(역할/저장 방식/중복/기능), 자료구조별 특성 |
인덱스는 정렬에서 출발 합니다. SELECT를 빠르게 하기 위해 INSERT/UPDATE/DELETE에서 비용을 지불하는 자료구조입니다.
8.3 B-Tree 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-3 B-Tree 인덱스 | 구조(루트/브랜치/리프), 키 추가/삭제, 카디널리티, 인덱스 레인지 스캔, 커버링 인덱스 |
MySQL에서 기본이자 가장 많이 쓰이는 인덱스 입니다. B-Tree의 구조와 동작을 이해하면 실행 계획을 읽는 감각이 생깁니다.
8.4 R-Tree 인덱스 (공간 인덱스)
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-4 R-Tree 인덱스 | MBR, GEOMETRY, 공간 검색 함수 |
지도/좌표 데이터처럼 2차원 이상의 데이터 를 다룰 때 사용됩니다.
8.5 전문 검색 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-5 전문 검색 인덱스 | 단어 단위 인덱싱, 불용어, n-gram, 어근 분석 |
긴 문서에서 단어로 검색 하기 위한 인덱스입니다. LIKE '%...%'의 한계를 해결합니다.
8.6 함수 기반 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-6 함수 기반 인덱스 | 가상 칼럼 인덱스 vs 함수 기반 인덱스 (MySQL 8.0+) |
WHERE SUBSTRING(name,1,3)='Geo'처럼 함수를 적용한 결과를 인덱스 로 만들 수 있습니다.
8.7 멀티 밸류 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-7 멀티 밸류 인덱스 | JSON 배열에 대한 인덱스 (MySQL 8.0.17+) |
하나의 레코드가 여러 값을 갖는 JSON 배열을 인덱싱합니다.
8.8 클러스터링 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-8 클러스터링 인덱스 | PK = 데이터 물리 정렬, 세컨더리 인덱스의 리프 = PK |
InnoDB의 핵심 설계 원리 입니다. “세컨더리 인덱스 = PK 값을 저장” 이 하나를 이해하면 MySQL 성능의 많은 부분이 설명됩니다.
8.9 유니크 인덱스
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-9 유니크 인덱스 | 유니크는 제약 조건, 성능 측면의 함정 |
유니크 인덱스는 성능을 위한 것이 아니라 제약 조건을 위한 것 입니다. 오히려 변경 시 비용이 더 큽니다.
8.10 외래키
| 서브노트 | 핵심 주제 |
|---|---|
| Ch08-10 외래키 | InnoDB 전용, 부모/자식 인덱스, CASCADE의 위험 |
외래키는 데이터 정합성을 위한 기능 이지만, 잠금 전파로 인해 데드락의 주범이 되기도 합니다.
정리
MySQL 인덱스 전체 지도
flowchart TD Root["인덱스"] subgraph 기준_역할["기준: 역할"] PK["프라이머리 키"] SEC["세컨더리 인덱스"] end subgraph 기준_저장방식["기준: 저장 방식"] BTREE["B-Tree"] HASH["Hash"] RTREE["R-Tree"] FULLTEXT["Full-text"] end subgraph 기준_중복["기준: 중복 허용"] UNIQ["Unique"] NONUNIQ["Non-unique"] end subgraph 기준_기능["기준: 기능"] FUNC["함수 기반"] MULTI["멀티 밸류"] SPATIAL["공간 검색"] end Root --> 기준_역할 Root --> 기준_저장방식 Root --> 기준_중복 Root --> 기준_기능
인덱스 선택 가이드
| 상황 | 권장 인덱스 |
|---|---|
| 일반적인 동등/범위 검색 | B-Tree |
| 정확히 일치하는 키-값 조회 (메모리 테이블) | Hash |
| 좌표/지도 데이터 | R-Tree |
| 긴 문서의 키워드 검색 | Full-text |
| JSON 배열 필드 검색 | 멀티 밸류 |
| 특정 함수를 자주 쓰는 WHERE 조건 | 함수 기반 |
내 생각
-
인덱스는 공짜가 아닙니다. 하나 추가할 때마다 저장 공간, 쓰기 비용, 버퍼 풀 점유, 옵티마이저 판단 시간이 증가합니다. “일단 인덱스부터 걸어보자”는 접근은 장기적으로 시스템을 느리게 만듭니다.
-
InnoDB 환경에서 가장 중요한 인덱스 원칙 두 가지: 1. PK는 작고 단조 증가해야 한다 / 2. 세컨더리 인덱스는 PK를 포함한다. 이 두 가지만 이해하면 인덱스 설계의 70%는 해결됩니다.
-
인덱스 튜닝은 실행 계획 읽기 → 옵티마이저 이해 → 인덱스 구조 이해 의 역순으로 공부하면 추상적입니다. 반대로 B-Tree의 물리적 동작을 먼저 이해하면, 실행 계획의 모든 항목이 자연스럽게 해석됩니다.
관련 개념
- Ch04-2 InnoDB 스토리지 엔진 — 버퍼 풀, 어댑티브 해시 인덱스, 체인지 버퍼
- Ch05-3 InnoDB 스토리지 엔진 잠금 — 인덱스와 잠금의 관계
- Ch09 옵티마이저와 힌트 (예정) — 옵티마이저가 인덱스를 선택하는 기준
- Ch10 실행 계획 (예정) — 인덱스 사용 여부 확인
출처
- Real MySQL 8.0 (1권), Ch08 인덱스