[UMC] 함수 기반 인덱스와 복합 인덱스

Backend·2025-09-17·by 1000hyehyang

드디어 UMC 1주차 마지막 시니어 미션이다.... 미션은 함수 기반 인덱스복합 인덱스 에 대해 조사하기!

  

함수 기반 인덱스 (Functional Indexes)

MySQL 8.0부터 expression index라는 기능이 추가되었다. 말 그대로 컬럼에 함수를 적용한 결과를 인덱스로 만들어주는 기능이다.

CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(100),
  INDEX idx_email_lower ((LOWER(email)))
);

예를 들어 이메일 검색을 할 때, 사용자가 대소문자 섞어서 입력하는 경우가 많다. 그런데 WHERE LOWER(email) = 'test@example.com' 같은 쿼리를 날리면, 일반 인덱스는 못 쓴다. 왜냐하면 LOWER(email)이라는 변환이 들어가 버렸기 때문이다. 이때 함수 기반 인덱스를 만들면, 이미 LOWER(email) 결과를 인덱스로 갖고 있으니까 바로 찾아낼 수 있다.

장점

  • 함수를 써도 인덱스를 활용 가능 (LOWER(), DATE(), SUBSTRING() 같은 자주 쓰이는 함수에 강하다)
  • 불필요한 full scan을 피하고 range scan으로 최적화 가능
  • 대소문자 무시 검색, 날짜별 집계 같은 패턴에 유용

단점

  • 데이터를 넣거나 바꿀 때마다 함수 계산 결과까지 갱신해야 해서 쓰기 성능에 부담
  • 인덱스를 활용하려면 쿼리에서 똑같은 함수/표현식을 써야 한다. 조금이라도 다르면 무용지물
  • 추가 인덱스가 생기니 스토리지 공간도 더 차지

  

복합 인덱스 (Composite Indexes)

복합 인덱스는 말 그대로 여러 개 컬럼을 묶어서 하나의 인덱스로 만든 것이다. MySQL에서는 multiple-column index라고도 한다.

CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_id INT,
  order_date DATE,
  amount DECIMAL(10,2),
  INDEX idx_customer_date (customer_id, order_date)
);

위 예시는 (customer_id, order_date) 두 개 컬럼을 인덱스로 묶은 것이다. 이러면 특정 고객의 주문 내역을 날짜 순으로 조회할 때 아주 빠르게 찾아낼 수 있다.

하지만 여기서 중요한 규칙이 있다. 바로 Leftmost Prefix Rule. 즉, 인덱스 정의에서 앞쪽 컬럼이 반드시 조건에 포함되어야 인덱스가 잘 작동한다.

-- 가능 (앞 컬럼 customer_id 사용)
SELECT * FROM orders WHERE customer_id = 123;

-- 가능 (앞 컬럼 + 다음 컬럼까지)
SELECT * FROM orders 
WHERE customer_id = 123 AND order_date >= '2025-01-01';

-- 비효율 (앞 컬럼 빠짐 → 인덱스 활용 어려움)
SELECT * FROM orders WHERE order_date >= '2025-01-01';

장점

  • 여러 컬럼 조합이 자주 조회될 때 성능 최적화
  • WHERE + ORDER BY, WHERE + GROUP BY 상황에서도 강력함
  • 커버링 인덱스로 활용하면 테이블 접근 없이 인덱스만으로 결과 뽑기 가능

단점

  • 선두 컬럼 규칙 때문에 컬럼 순서가 매우 중요
  • 컬럼이 많아질수록 인덱스 크기 커지고 관리 비용 증가
  • 자주 업데이트되는 컬럼이 섞여 있으면 DML 성능 저하

이건 부트캠프를 하면서 멘토님께 들었던 내용인데, 인덱스는 다다익선이라고 하셨다.

어차피 대부분의 서비스에서 읽기 비중이 압도적으로 크다.

특히 대규모 트래픽 서비스에서 인덱스 최적화가 없으면 쿼리 응답 시간이 치명적으로 길어진다. 이때는 쓰기 성능 조금 희생해도 인덱스를 적극적으로 쓰는 게 훨씬 효율적이라고 말씀하셨다.

댓글 로딩 중...