개발자 팁SQL 팁 › 인덱스를 만들었는데 안 타는 경우 — 옵티마이저가 무시하는 조건들

인덱스를 만들었는데 안 타는 경우 — 옵티마이저가 무시하는 조건들

2026-08-28 · SQL 팁
한 줄 요약

인덱스가 있는데 풀스캔이 나오는 대표적 원인 여섯 가지와 확인 방법.

먼저 실행 계획을 본다

"인덱스를 만들었는데 느리다"는 상황에서 가장 먼저 할 일은 추측이 아니라 확인이다.

```sql

EXPLAIN ANALYZE

SELECT * FROM orders WHERE created_at >= '2026-08-01';

```

EXPLAIN은 예상 계획, EXPLAIN ANALYZE는 실제 실행 결과다. 예상 행 수와 실제 행 수가 크게 다르면 통계가 낡은 것이므로 그것부터 갱신한다.

원인 1 — 컬럼에 함수를 씌움

가장 흔하다.

```sql

-- 인덱스 못 씀

WHERE DATE(created_at) = '2026-08-01'

WHERE UPPER(email) = 'A@B.COM'

-- 인덱스 사용 가능

WHERE created_at >= '2026-08-01' AND created_at < '2026-08-02'

WHERE email = 'a@b.com'

```

인덱스는 컬럼의 원본 값으로 정렬돼 있다. 함수를 거치면 그 값이 아니게 되므로 정렬을 활용할 수 없다.

함수를 꼭 써야 한다면 함수 기반 인덱스를 별도로 만드는 방법이 있다.

원인 2 — 타입 불일치

```sql

-- user_id가 VARCHAR인데 숫자로 비교

WHERE user_id = 12345

```

암묵적 형변환이 일어나면서 인덱스를 못 쓰는 경우가 있다. 파라미터 타입을 컬럼 타입에 맞춘다.

원인 3 — 선택도가 낮음

전체의 상당 비율을 가져오는 조건이면 인덱스를 타는 것이 오히려 느리다. 인덱스로 위치를 찾고 다시 테이블을 읽는 왕복이 발생하기 때문이다.

```sql

-- status가 두 종류뿐이고 대부분 'active'라면

WHERE status = 'active' -- 풀스캔이 더 빠를 수 있음

```

이 경우는 옵티마이저의 판단이 옳다. 인덱스를 강제할 것이 아니라 조건을 좁히거나 부분 인덱스를 고려한다.

원인 4 — 복합 인덱스의 순서

인덱스 (a, b, c)가 있을 때:

| 조건 | 활용 |

|---|---|

| a = ? | 사용 |

| a = ? AND b = ? | 사용 |

| a = ? AND c = ? | a까지만 사용 |

| b = ? | 대체로 못 씀 |

| b = ? AND c = ? | 대체로 못 씀 |

선행 컬럼이 조건에 있어야 한다. 자주 쓰는 조건 조합을 보고 순서를 정한다. 등호 조건 컬럼을 앞에, 범위 조건 컬럼을 뒤에 두는 것이 일반적인 지침이다.

원인 5 — OR 조건

```sql

WHERE a = 1 OR b = 2

```

각각에 인덱스가 있어도 OR로 묶이면 활용이 어려운 경우가 있다. UNION으로 분리하면 각 인덱스를 쓸 수 있다.

```sql

SELECT * FROM t WHERE a = 1

UNION

SELECT * FROM t WHERE b = 2

```

원인 6 — 앞이 열린 LIKE

```sql

WHERE name LIKE '%김%' -- 못 씀

WHERE name LIKE '김%' -- 사용 가능

```

인덱스는 앞에서부터 정렬돼 있으므로, 앞이 와일드카드면 시작 지점을 찾을 수 없다. 앞뒤 모두 열린 검색이 필요하면 전문 검색 인덱스를 고려한다.

확인 순서

  1. EXPLAIN ANALYZE로 실제 계획 확인
  2. 예상 행 수와 실제 행 수 비교 → 다르면 통계 갱신
  3. 위 여섯 원인 중 해당하는 것이 있는지 확인
  4. 인덱스 정의와 조건절의 컬럼 순서 대조

인덱스를 추가하기 전에 이 순서를 밟으면, 안 쓰이는 인덱스를 늘리는 것을 피할 수 있다. 인덱스는 조회를 돕지만 쓰기 비용과 저장 공간을 늘린다.

최종 수정 2026-08-28

자주 묻는 질문

인덱스가 있는데 왜 풀스캔이 나오나요?

컬럼에 함수를 씌우거나 타입이 다르거나, 조회 대상이 전체의 상당 비율이면 옵티마이저가 풀스캔을 선택합니다.

복합 인덱스는 순서가 중요한가요?

중요합니다. 선행 컬럼이 조건에 없으면 대체로 인덱스를 활용하지 못합니다.

실행 계획을 어떻게 보나요?

EXPLAIN(또는 EXPLAIN ANALYZE)으로 확인합니다. 예상 계획과 실제 실행은 다를 수 있어 ANALYZE 쪽이 정확합니다.

DB Linker로 지금 시작하기

AI 채팅으로 데이터베이스를 조회·관리하는 로컬 전용 개발자 도구. 자체 서버 없이 이용자의 기기에서만 동작합니다.

App Store에서 받기 →

안내

이 글은 일반적인 데이터베이스 관리 원칙과 개발 관행을 다루는 콘텐츠이며, 특정 프로젝트·프로덕션 환경에 대한 전문적 조언을 대체하지 않습니다. 구체적 버전·수치가 언급되더라도 실제 사용 중인 도구·버전에서 반드시 재확인하시기 바랍니다.

글 중 일부는 AI 도구의 도움을 받아 초안을 작성한 뒤 발행됩니다. 내용 중 사실과 다르거나 수정이 필요한 부분을 발견하시면 GitHub Issues로 알려주세요.