인덱스
데이터를 빠르게 찾기 위한 자료구조입니다. 책의 색인(목차)과 같습니다.
비유
책에서 "React" 찾기:
인덱스 없음: 1페이지부터 끝까지 전부 읽음
인덱스 있음: 색인에서 "React → 152페이지" 확인 → 바로 이동
인덱스 없을 때
SELECT * FROM users WHERE name = '철수';
테이블 전체 스캔 (Full Table Scan)
| id | name | age |
|----|--------|-----|
| 1 | 영희 | 25 | ← 확인
| 2 | 민수 | 30 | ← 확인
| 3 | 철수 | 28 | ← 찾음!
| 4 | 지연 | 22 | ← 확인 (끝까지 계속)
...
100만 건이면 100만 번 확인합니다.
인덱스 있을 때
CREATE INDEX idx_name ON users(name);
인덱스 (B-Tree)
[민수]
/ \
[영희] [철수]
/
[지연]
철수 찾기: 민수 → 오른쪽 → 철수 (3번 비교)
100만 건이어도 약 20번 비교로 찾습니다.
인덱스 자료구조
| 구조 | 특징 | DB 적합성 |
|---|---|---|
| B-Tree / B+Tree | 정렬된 균형 트리 | 범위 검색·정렬 가능 → 대부분의 RDB 기본값 |
| HashMap (해시) | 해시 함수로 O(1) 조회 | 등치만 가능. 범위·정렬 불가 → MEMORY 엔진, Redis 등 |
→ MySQL InnoDB는 B+Tree를 사용 (리프 노드끼리 연결리스트 → 범위 검색 빠름).
인덱스 종류
| 구분 | 설명 |
|---|---|
| Clustered Index | 데이터 자체가 정렬되어 저장. 테이블당 1개 (보통 PK) |
| Non-Clustered Index | 별도 인덱스 페이지 → 데이터 포인터. 여러 개 가능 |
| 복합 인덱스 | 여러 컬럼을 묶은 인덱스 |
| Hidden Clustered Index | InnoDB가 PK 없을 때 자동 생성 |
장단점
| 장점 | 단점 |
|---|---|
| 조회 빠름 | 저장 공간 추가 필요 |
| 정렬 빠름 | INSERT/UPDATE/DELETE 느려짐 |
-- INSERT 시
1. 테이블에 데이터 추가
2. 인덱스도 업데이트 (추가 작업)
언제 만드는가
-- 좋은 경우
CREATE INDEX idx_email ON users(email); -- 자주 검색하는 컬럼
CREATE INDEX idx_created ON orders(created_at); -- 정렬에 쓰는 컬럼
-- 안 좋은 경우
CREATE INDEX idx_gender ON users(gender); -- 값이 몇 개 없음 (남/여)
| 좋은 경우 | 나쁜 경우 |
|---|---|
| WHERE절에 자주 사용 | 거의 조회 안 하는 컬럼 |
| 카디널리티 높음 (값 종류 많음) | 카디널리티 낮음 (남/여 등) |
| 조회 > 쓰기 | 쓰기 > 조회 |
주의
만들었다고 항상 타지는 않습니다 → 인덱스가 안 타는 케이스 참고.