databasebackend
복합 인덱스, 순서가 전부다
조회 0
(status, published_at) 인덱스가 있는데 왜 published_at만으로 조회하면 풀스캔일까? 복합 인덱스를 "두 컬럼 다 빨라지는 마법"으로 이해하면 생기는 오해다.
전화번호부 비유
복합 인덱스는 첫 컬럼으로 정렬하고, 같은 값 안에서 둘째 컬럼으로 정렬한 전화번호부다. (성, 이름) 순으로 정렬된 명부에서 "성이 김씨인 사람"은 빨리 찾지만, "이름이 경원인 사람"은 처음부터 끝까지 뒤져야 한다.
CREATE INDEX idx ON posts (status, published_at);
-- ✅ 인덱스 탄다
WHERE status = 'PUBLISHED' AND published_at > '2026-01-01'
WHERE status = 'PUBLISHED'
-- ❌ 못 탄다 (선두 컬럼 없음)
WHERE published_at > '2026-01-01'
순서 정하는 법
- 등호(=) 조건 컬럼을 앞에, 범위(>, <, BETWEEN) 컬럼을 뒤에. 범위 조건 뒤의 컬럼은 인덱스 효과가 급감한다
- 항상 함께 쓰는 필터(테넌트 id, status 같은)가 선두
- ORDER BY까지 인덱스로 해결하려면 정렬 컬럼이 마지막에
-- "발행 글을 최신순으로" 를 통째로 커버
CREATE INDEX idx ON posts (status, published_at DESC);
확인은 EXPLAIN으로
EXPLAIN ANALYZE
SELECT * FROM posts
WHERE status = 'PUBLISHED'
ORDER BY published_at DESC LIMIT 20;
Index Scan + Sort 노드가 없으면 정렬까지 인덱스가 흡수한 것. Seq Scan이 보이면 순서를 다시 보자.
인덱스를 늘리기 전에 순서를 먼저 의심하라. 대부분의 "인덱스 있는데 느려요"는 순서 문제다.