인덱스는 테이블의 데이터를 더 빠르게 찾기 위해 특정 컬럼의 값과 행의 위치 정보를 별도의 자료구조로 저장한 것입니다. MySQL의 일반적인 인덱스는 B-Tree 계열로 구성되어 전체 테이블을 순차 탐색하지 않고도 값이나 범위를 찾을 수 있습니다.

인덱스는 다음과 같은 경우에 효과적입니다.

  • 큰 테이블에서 일부 행만 찾는 선택도 높은 WHERE 조건
  • 조인에 자주 사용하는 외래 키나 연결 컬럼
  • 인덱스 순서를 활용할 수 있는 ORDER BY, GROUP BY, 범위 조회
  • 중복을 허용하지 않아야 하는 PRIMARY KEY, UNIQUE 제약

반면 다음과 같은 경우에는 효과가 작거나 비용이 더 클 수 있습니다.

  • 행 수가 적어 전체 스캔이 더 저렴한 테이블
  • 대부분의 행을 조회하는 쿼리나 단독으로 사용했을 때 선택도가 매우 낮은 컬럼
  • INSERT, UPDATE, DELETE가 매우 빈번한 테이블에 과도하게 많은 인덱스를 두는 경우
  • 크기가 큰 문자열을 그대로 포함하거나 실제 쿼리에서 거의 사용하지 않는 인덱스

인덱스는 읽기 속도를 공짜로 높이는 기능이 아닙니다. 별도의 저장 공간을 사용하고 데이터 변경 시 인덱스도 함께 갱신해야 합니다. 따라서 예상만으로 추가하기보다 실제 쿼리와 데이터 분포를 기준으로 실행 계획과 성능을 측정해야 합니다.

사용자가 별도의 인덱스를 직접 명시하지 않아도 조건에 만족한다면 인덱스를 통해 데이터를 조회한다. 이는 옵티마이저로 인해 인덱스가 선택되기 때문이다.

출처 및 참고자료