`(user_id, order_date, status)` 인덱스는 세 조건을 따로 찾는 구조가 아니라, user_id로 범위를 잡고 그 안에서 order_date, 그다음 status를 읽는 순서입니다.
인덱스 정의
INDEX (user_id, order_date, status)
앞 단계가 고정되어야 다음 단계 정렬이 의미를 가집니다. 중간이 끊기면 그 뒤 조건은 인덱스 탐색이 아니라 후처리 필터에 가까워집니다.
가장 먼저 사용자 범위를 찾습니다. 이 시작점이 없으면 뒤 컬럼으로 바로 들어갈 수 없습니다.
같은 user_id 안에서 날짜 순서를 활용합니다. `=`도, 범위 조건도 여기까지는 탈 수 있습니다.
앞 두 값이 이어질 때만 마지막 정렬 기준이 됩니다. 중간 컬럼을 건너뛰면 여기까지 못 갑니다.
왼쪽부터 연속으로 맞으면 사용, 선두가 빠지면 불가, 중간을 건너뛰면 그 지점까지만 사용됩니다.
| 쿼리 패턴 | 인덱스 판정 | 왜 이렇게 동작하나 |
|---|---|---|
WHERE user_id = 1001 AND order_date = '2024-01-01' AND status = 'PENDING' |
사용 가능
A → B → C
또는 A, A+B까지도 사용 |
선두 컬럼부터 끊기지 않고 이어집니다. `WHERE user_id = 1001`, `AND order_date > '2024-01-01'` 같은 형태도 A 다음 B까지는 그대로 활용됩니다. |
WHERE order_date = '2024-01-01' WHERE status = 'PENDING' |
사용 불가
B만 또는 C만 조건
|
인덱스는 먼저 user_id 묶음으로 정렬되어 있습니다. 선두 컬럼이 없으면 날짜나 상태만으로는 원하는 구간에 바로 점프할 수 없습니다. |
WHERE user_id = 1001 AND status = 'PENDING' |
부분 사용
A만 사용
B를 건너뜀 |
`user_id = 1001` 범위는 인덱스로 좁히지만, 그 안에서 status는 바로 이어진 정렬 키가 아니라서 추가 필터링이 필요합니다. 즉, 뒤 컬럼이 아니라 앞 prefix까지만 탑니다. |