한 줄 정의

인덱스는 데이터를 정렬해 보관 함으로써 검색 비용을 낮추는 자료구조이며, 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의 물리적 동작을 먼저 이해하면, 실행 계획의 모든 항목이 자연스럽게 해석됩니다.

관련 개념

출처

  • Real MySQL 8.0 (1권), Ch08 인덱스