포스트

데이터베이스 인덱스를 어떻게 이해해야 하는가

인덱스는 왜 필요한가

인덱스는 결국 조회를 빠르게 하기 위한 자료구조다. 테이블의 모든 행을 처음부터 끝까지 훑는 대신, 정렬된 별도 구조를 통해 원하는 레코드에 빠르게 도달하게 한다.

책의 목차나 색인과 비슷하게 비유할 수 있지만, 실무에서는 “읽기 성능을 위해 쓰기 비용과 저장 공간을 추가로 지불하는 장치”로 이해하는 편이 더 정확하다.

어떤 쿼리에 도움이 되나

  • WHERE
  • JOIN
  • ORDER BY
  • GROUP BY
  • UNIQUE 제약

다만 “컬럼에 인덱스가 있다”와 “쿼리가 인덱스를 잘 탄다”는 다른 이야기다. 조건 순서, 함수 사용 여부, 범위 조건 유무에 따라 실제 활용도는 크게 달라진다.

가장 흔한 구조

대부분의 RDBMS는 B-Tree 또는 B+Tree 계열 인덱스를 쓴다.

  • 정확한 값 검색에 강함
  • 범위 검색에도 유리함
  • 정렬된 순서를 유지함

그래서 =뿐 아니라 <, >, BETWEEN, 정렬 쿼리에도 넓게 쓰인다.

인덱스의 비용

장점만 보면 무조건 많이 만드는 게 좋아 보이지만 실제로는 아니다.

  • INSERT/UPDATE/DELETE가 느려질 수 있다.
  • 저장 공간을 추가로 사용한다.
  • 잘못 설계한 인덱스는 optimizer를 오히려 헷갈리게 할 수 있다.

즉, 인덱스는 “많을수록 좋다”가 아니라 “자주 쓰는 접근 패턴에 맞는 것만 정확히 둔다”가 원칙이다.

복합 인덱스에서 중요한 것

복합 인덱스는 선두 컬럼 기준으로 동작한다.

예:

1
2
CREATE INDEX idx_orders_status_created_at
ON orders(status, created_at);

이 경우 보통 다음은 잘 활용된다.

  • where status = ?
  • where status = ? and created_at > ?

반면 where created_at > ?만 단독으로 쓰면 기대만큼 못 탈 수 있다.

선택도가 낮은 컬럼은 주의

boolean, 성별, 상태처럼 값 종류가 아주 적은 컬럼은 단독 인덱스 효율이 낮을 수 있다. 하지만 데이터 분포가 극단적으로 한쪽으로 치우쳐 있으면 예외가 생길 수 있다.

즉, “boolean은 무조건 인덱스 의미 없음” 같은 식으로 단정하면 안 되고, 실제 분포와 쿼리 패턴을 같이 봐야 한다.

클러스터드 vs 보조 인덱스

InnoDB 기준으로는 PK가 클러스터드 인덱스 역할을 한다.

  • 클러스터드 인덱스: 데이터 자체가 PK 기준으로 정렬
  • 보조 인덱스: 인덱스 키 + PK를 저장

그래서 보조 인덱스로 조회한 뒤 실제 row를 찾기 위해 한 번 더 따라가는 비용이 생길 수 있다.

실무 체크포인트

  • 실제로 느린 쿼리인가
  • 어떤 조건과 정렬로 자주 호출되는가
  • 카디널리티와 데이터 분포가 어떤가
  • EXPLAIN에서 인덱스를 기대대로 타는가
  • 인덱스 추가 후 쓰기 비용 증가가 감당 가능한가

정리

인덱스는 조회 최적화의 핵심이지만, SQL 패턴과 데이터 분포를 함께 보지 않으면 금방 “있는데도 안 쓰는” 상태가 된다. 좋은 인덱스 설계는 문법보다도 실제 접근 패턴을 읽는 데서 시작한다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

댓글

아직 댓글이 없습니다