[DB] 10. 인덱스(Index)와 성능 최적화

[DB] 10. 인덱스(Index)와 성능 최적화

1. 인덱스(Index)란?

인덱스는 데이터베이스에서 데이터를 빠르게 찾기 위해 사용하는 구조다.

책의 맨 앞에 있는 목차를 떠올리면 이해하기 쉽다. 목차가 있으면 원하는 페이지를 바로 찾을 수 있고, 없으면 처음부터 끝까지 넘겨봐야 한다.

데이터베이스에서도 인덱스가 없으면 조건에 맞는 데이터를 찾기 위해 테이블 전체를 하나씩 확인해야 한다.

2. 인덱스가 없는 경우의 조회 방식

인덱스가 없는 상태에서 WHERE 조건으로 조회하면, DBMS는 테이블의 모든 행을 하나씩 검사한다.

이를 풀 테이블 스캔(Full Table Scan)이라고 한다.

데이터가 적을 때는 큰 문제가 없지만, 행의 수가 수십만, 수백만 개로 늘어나면 조회 성능은 급격히 떨어진다.

3. 인덱스가 있는 경우의 조회 방식

인덱스가 존재하면, DBMS는 인덱스를 먼저 탐색해 조건에 맞는 데이터의 위치를 빠르게 찾는다.

그 후 실제 테이블에서 필요한 행만 읽어온다.

이 덕분에 조회 속도가 크게 개선된다.

4. 인덱스의 내부 구조 (개념)

대부분의 관계형 DBMS는 인덱스를 B-Tree 또는 B+Tree 구조로 관리한다.

이 구조의 특징은 데이터가 정렬된 상태로 저장되며, 탐색 시 단계적으로 범위를 좁혀갈 수 있다는 점이다.

그래서 인덱스는 =, <, >, BETWEEN 같은 조건에서 특히 효과적이다.

5. 인덱스를 사용하면 항상 좋은가?

인덱스는 조회 성능을 높여주지만, 항상 좋은 것은 아니다.

인덱스에는 분명한 비용이 따른다.

  • INSERT 시 인덱스도 함께 갱신해야 한다
  • UPDATE 시 인덱스 재정렬이 발생할 수 있다
  • DELETE 시 인덱스에서도 제거해야 한다
  • 추가 저장 공간이 필요하다

즉, 인덱스는 읽기 성능을 얻는 대신 쓰기 성능을 일부 희생하는 구조다.

6. 어떤 컬럼에 인덱스를 걸어야 하는가

아무 컬럼에나 인덱스를 걸면 오히려 성능이 나빠질 수 있다.

다음 기준을 참고하는 것이 일반적이다.

  • WHERE 조건에 자주 사용되는 컬럼
  • JOIN 조건에 사용되는 컬럼(FK)
  • ORDER BY, GROUP BY에 자주 사용되는 컬럼

반대로, 값의 종류가 매우 적은 컬럼(예: 성별, 상태값)은 인덱스 효율이 낮은 경우가 많다.

7. 카디널리티(Cardinality)

카디널리티는 컬럼에 존재하는 값의 중복 정도를 의미한다.

값의 종류가 많을수록 카디널리티가 높다고 말한다.

일반적으로 카디널리티가 높은 컬럼일수록 인덱스 효율이 좋다.

8. 복합 인덱스(Composite Index)

복합 인덱스는 두 개 이상의 컬럼을 묶어서 만든 인덱스다.

예를 들어 (user_id, created_at) 인덱스가 있다면, 다음 조건에서는 인덱스를 사용할 수 있다.

  • user_id = ?
  • user_id = ? AND created_at > ?

하지만 created_at만으로 조회하면 이 인덱스는 사용되지 않는다.

이를 인덱스의 선두 컬럼 규칙이라고 한다.

9. 인덱스를 사용할 수 없는 경우

다음과 같은 경우에는 인덱스가 있어도 사용되지 않을 수 있다.

  • 컬럼에 함수가 적용된 경우
  • LIKE '%값' 형태의 조건
  • 암시적 형 변환이 발생하는 경우
  • 데이터 양이 너무 적은 경우

10. 정리

  • 인덱스는 조회 성능을 높이기 위한 구조다
  • 인덱스가 없으면 풀 테이블 스캔이 발생한다
  • 인덱스는 쓰기 성능과 저장 공간 비용을 가진다
  • 자주 조회되는 컬럼에 신중하게 적용해야 한다