인덱스(Index)와 실행계획(Explain Plan)
데이터베이스 성능 튜닝에서 가장 먼저 배우고 가장 자주 쓰이는 개념이 바로 인덱스(Index) 와 실행계획(Explain Plan) 입니다.

1. 인덱스(Index)란?
사전에서 단어 찾기와 비슷하다
- 책에서 특정 단어를 찾을 때 인덱스(찾아보기) 를 보면 바로 해당 페이지를 알 수 있죠.
- 데이터베이스도 마찬가지로, 인덱스를 사용하면 특정 데이터를 더 빨리 찾을 수 있습니다.
👉 즉, 인덱스는 데이터를 빠르게 조회하기 위한 자료구조입니다.
인덱스 없는 검색 (Full Table Scan)
SELECT * FROM member WHERE name = '홍길동';
- name 컬럼에 인덱스가 없으면, DB는 member 테이블을 처음부터 끝까지 뒤져야 합니다. (Full Table Scan)
- 데이터가 수천만 건이면? → 엄청 느려짐
인덱스 있는 검색 (Index Scan)
CREATE INDEX idx_member_name ON member(name); SELECT * FROM member WHERE name = '홍길동';
- 이제 name 컬럼에 인덱스가 있으니, DB는 인덱스를 통해 바로 해당 위치로 찾아갈 수 있습니다.
- 성능 차이는 수십 배 이상 날 수 있음
2. 인덱스의 특징
장점
- 검색 속도 향상
- WHERE, JOIN, ORDER BY 절에서 빠른 성능
- 시스템 부하 감소
- 불필요한 데이터 조회를 줄임
단점
- INSERT, UPDATE, DELETE 성능 저하
- 데이터가 변경될 때마다 인덱스도 갱신해야 함
- 저장 공간 증가
- 인덱스 자체도 별도의 자료구조(B-Tree 등)로 저장됨
👉 조회가 많고 변경이 적은 컬럼에 인덱스를 걸어야 효율적
3. 실행계획(Explain Plan)이란?
쿼리를 날리면 DB는 내부적으로 “어떻게 데이터를 읽을지”를 계획(Plan) 을 세웁니다.
이를 눈으로 확인할 수 있는 게 실행계획(Explain Plan) 입니다.
👉 쉽게 말해, “DB가 쿼리를 어떤 순서로 처리하는지 보여주는 지도” 라고 할 수 있습니다.
실행계획 보는 방법
MySQL
EXPLAIN SELECT * FROM member WHERE name = '홍길동';
PostgreSQL
EXPLAIN ANALYZE SELECT * FROM member WHERE name = '홍길동';
👉 EXPLAIN 은 실행 계획만 보여주고,
👉 EXPLAIN ANALYZE 는 실제 실행까지 해서 소요 시간도 보여줍니다.
4. 실행계획 예시
(1) 인덱스 없는 경우
EXPLAIN SELECT * FROM member WHERE name = '홍길동';
결과 예시 (MySQL):
id | select_type | table | type | possible_keys | key | rows | Extra
---+-------------+--------+------+---------------+------+-------+-------
1 | SIMPLE | member | ALL | NULL | NULL | 10000 | Using where
- type = ALL → 전체 테이블 스캔 (Full Table Scan)
- rows = 10000 → 1만 건을 다 뒤져야 함
(2) 인덱스 있는 경우
CREATE INDEX idx_member_name ON member(name); EXPLAIN SELECT * FROM member WHERE name = '홍길동';
결과 예시:
id | select_type | table | type | possible_keys | key | rows | Extra
---+-------------+--------+------+---------------+------------------+------+-------
1 | SIMPLE | member | ref | idx_member_name | idx_member_name | 1 | Using index
- type = ref → 인덱스를 사용한 검색
- rows = 1 → 필요한 데이터만 조회
👉 Full Table Scan → Index Scan 으로 바뀌면서 성능이 크게 개선됨
5. 인덱스 사용이 잘 안 되는 경우
1. 함수 사용
SELECT * FROM member WHERE LOWER(name) = 'hong';
→ LOWER(name) 때문에 인덱스 사용 불가
2. 앞부분 불일치 (LIKE 검색)
SELECT * FROM member WHERE name LIKE '%길동';
→ %로 시작하면 인덱스 못 씀 (홍길% 는 가능)
3. 조건이 너무 광범위할 때
SELECT * FROM member WHERE age > 0;
→ 사실상 전체 데이터 → 인덱스 의미 없음
6. 실무 팁
1. 항상 실행계획으로 확인하기
- 쿼리 튜닝할 때 “인덱스 걸었으니 빨라졌겠지?”가 아니라,
- EXPLAIN 으로 실제 동작을 확인해야 함
2. 인덱스는 SELECT 최적화용, INSERT/UPDATE에는 부담
- 로그성 데이터처럼 INSERT가 잦으면 인덱스 최소화
3. 복합 인덱스 사용 시 컬럼 순서 주의
CREATE INDEX idx_user_name_age ON user(name, age);
- WHERE name = '홍길동' → 인덱스 사용
- WHERE age = 30 → 인덱스 못 씀 (앞 컬럼이 먼저 사용되어야 함)
7. 정리
- 인덱스(Index) 는 빠른 검색을 위한 데이터 구조
- 잘 쓰면 성능이 수십 배 개선되지만, 남용하면 오히려 성능 저하
- 실행계획(Explain Plan) 은 DB가 쿼리를 어떻게 실행하는지 보여주는 지도
- 항상 EXPLAIN 으로 확인하면서 쿼리를 튜닝해야 한다
👉 “인덱스를 언제, 왜 쓰는지”와 “실행계획을 읽는 방법”에 대해 알아봤습니다.
