인덱스 (Index)
인덱스: 테이블의 특정 컬럼에 대해 빠른 검색을 가능하게 하는 자료구조. 책의 "색인"처럼 원하는 데이터를 전체 테이블을 읽지 않고도 빠르게 찾을 수 있게 한다.
인덱스 문서는 한 번에 읽기 쉽도록 개요와 상세 문서로 나눈다. 처음 보는 사람은 이 문서에서 흐름을 잡고, 필요한 상황에 맞는 상세 문서로 이동하면 된다.
먼저 보는 큰 그림
왜 필요한가?
-> Full Table Scan을 줄이고 필요한 행을 빠르게 찾는다.
어떻게 동작하는가?
-> MySQL InnoDB는 주로 B+Tree, 클러스터 인덱스, 보조 인덱스로 처리한다.
어떻게 설계하는가?
-> 카디널리티, 커버링 인덱스, 복합 인덱스 컬럼 순서를 기준으로 판단한다.
왜 안 타는가?
-> 함수 적용, 앞쪽 와일드카드 LIKE, 부정 조건, Range 이후 컬럼 같은 패턴을 확인한다.
운영에서는 무엇을 보는가?
-> EXPLAIN, 통계 갱신, 미사용 인덱스, 단편화, Online DDL을 함께 본다.
파워링크
| 상황 | 바로가기 | 핵심 질문 |
|---|---|---|
| 인덱스가 뭔지, 내부에서 어떻게 저장되는지 알고 싶다 | 구조와 종류 | B+Tree, 클러스터 인덱스, 보조 인덱스가 어떻게 다른가? |
| B-Tree와 B+Tree의 구조 차이를 자세히 보고 싶다 | B-Tree VS B+Tree | 왜 DB 인덱스는 B+Tree를 선호하는가? |
| 어떤 컬럼에 인덱스를 걸지 판단해야 한다 | 설계와 사용법 | 카디널리티가 충분한가? 커버링 인덱스가 가능한가? |
| 인덱스를 만들고 조회·수정·삭제하는 SQL이 필요하다 | 설계와 사용법 | CREATE, ALTER, DROP을 어떻게 쓰는가? |
| 인덱스가 있는데도 쿼리가 느리다 | 쿼리 패턴 | WHERE 조건이 인덱스를 무력화하고 있지 않은가? |
| 복합 인덱스 컬럼 순서가 헷갈린다 | 쿼리 패턴 | Equality, Sort, Range 순서를 지키고 있는가? |
| 운영 중 인덱스를 추가·삭제해야 한다 | 운영과 튜닝 | Online DDL, 인비저블 인덱스, 통계 갱신을 어떻게 활용하는가? |
| 슬로우 쿼리를 분석해야 한다 | 운영과 튜닝 | EXPLAIN, ANALYZE TABLE, 미사용 인덱스 점검 순서는? |
| 인덱스를 타는데도 Full Scan보다 느린 이유가 궁금하다 | 손익분기점 | 읽는 행 비율, 커버링 여부, 랜덤 I/O 비용을 함께 보고 있는가? |
| 랜덤 I/O와 순차 I/O 차이를 이해하고 싶다 | 랜덤 I/O VS 순차 I/O | 보조 인덱스 Double Lookup이 왜 비싸지는가? |
추천 학습 순서
- 구조와 종류에서 B+Tree와 InnoDB 저장 구조를 먼저 잡는다.
- B-Tree VS B+Tree에서 두 구조의 차이와 DB가 B+Tree를 선호하는 이유를 확인한다.
- 설계와 사용법에서 어떤 컬럼에 인덱스를 걸지 판단한다.
- 쿼리 패턴에서 인덱스를 타는 조건과 무력화되는 조건을 비교한다.
- 운영과 튜닝에서 실제 운영 중 추가·삭제·모니터링 방법을 확인한다.
빠른 판단 기준
| 판단 | 기준 |
|---|---|
| 인덱스를 고려할 때 | WHERE, JOIN, ORDER BY, GROUP BY에 자주 쓰이고 선택도가 높은 컬럼 |
| 인덱스를 피할 때 | 값 종류가 적거나, 대부분의 행을 읽거나, 쓰기 비용이 더 중요한 테이블 |
| 먼저 확인할 것 | EXPLAIN에서 type, key, rows, Extra 확인 |
| 자주 하는 실수 | SELECT *, 컬럼에 함수 적용, LIKE '%값', 부정 조건, 무분별한 복합 인덱스 추가 |
| 운영 원칙 | 추가 전 실행 계획 확인, 삭제 전 인비저블 인덱스 검증, 통계 갱신 후 재확인 |