인덱스(Index)와 실행계획(Explain Plan)

2025. 9. 30. 19:50·Database

인덱스(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. 인덱스의 특징

장점

  1. 검색 속도 향상
    • WHERE, JOIN, ORDER BY 절에서 빠른 성능
  2. 시스템 부하 감소
    • 불필요한 데이터 조회를 줄임

단점

  1. INSERT, UPDATE, DELETE 성능 저하
    • 데이터가 변경될 때마다 인덱스도 갱신해야 함
  2. 저장 공간 증가
    • 인덱스 자체도 별도의 자료구조(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 으로 확인하면서 쿼리를 튜닝해야 한다

👉 “인덱스를 언제, 왜 쓰는지”와 “실행계획을 읽는 방법”에 대해 알아봤습니다.

저작자표시 (새창열림)
'Database' 카테고리의 다른 글
  • DB 테이블 설계 시 자주 부딪히는 두 가지 고민: 매핑 테이블 vs 별도 엔티티, 공통 코드 vs 개별 코드
  • DB Isolation Level
  • 데이터베이스 락(Lock)
쭈니어 개발자
쭈니어 개발자
    홈 |
  • 쭈니어 개발자
    주니어 개발자 공부 기록
    쭈니어 개발자
  • 글쓰기 관리
  • 전체
    오늘
    어제
  • GitHub

    Notion

    • 분류 전체보기 (134)
      • Frontend (4)
      • Backend (21)
      • Database (4)
      • Data Structure & Algorithm (41)
      • Network (16)
      • IT Education (48)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    자바
    코테
    트리의 지름
    백준
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.4
쭈니어 개발자
인덱스(Index)와 실행계획(Explain Plan)
상단으로

티스토리툴바