DB

[MySQL] 실무에서 인덱스가 무시되는 이유와 해결법 완전 분석

인생아 2025. 7. 3. 23:33
반응형

MySQL에서 인덱스는 성능 향상의 핵심 도구이다. 하지만 의도한 대로 인덱스가 사용되지 않는 경우도 흔하며, 이는 곧 성능 저하로 직결된다. 

🧩 인덱스가 무시되는 대표적인 원인

🔍 1. 함수 또는 연산 사용

인덱스가 걸린 컬럼에 함수나 산술 연산을 적용하면 인덱스가 무시된다.

-- 인덱스 무시됨
SELECT * FROM users WHERE YEAR(created_at) = 2023;

-- 해결법: 범위 조건 사용
SELECT * FROM users 
WHERE created_at >= '2023-01-01' AND created_at < '2024-01-01';
반응형

⚠️ 2. 데이터 타입 불일치

조건절 비교 시 데이터 타입이 다르면 암묵적 형변환이 발생하며, 이로 인해 인덱스를 무시할 수 있다.

-- created_at이 DATETIME인데 문자열과 비교하면 인덱스 미사용
SELECT * FROM users WHERE created_at = '2024-01-01';

-- 해결법: 날짜 리터럴 명확히 처리
SELECT * FROM users WHERE created_at = CAST('2024-01-01' AS DATETIME);

📏 3. LIKE의 패턴이 비효율적인 경우

인덱스는 LIKE '검색%'처럼 접두사 일치일 때만 사용 가능하다.

-- 인덱스 미사용
SELECT * FROM users WHERE name LIKE '%son';

-- 인덱스 사용
SELECT * FROM users WHERE name LIKE 'son%';

🔄 4. OR 조건의 사용

OR 조건이 모든 컬럼에 인덱스가 없으면, 전체 인덱스를 무시하고 풀스캔한다.

-- 인덱스 미사용 가능성 높음
SELECT * FROM users WHERE email = 'test@test.com' OR name = '홍길동';

-- 해결법: UNION으로 분리
SELECT * FROM users WHERE email = 'test@test.com'
UNION
SELECT * FROM users WHERE name = '홍길동';
반응형

📉 5. 통계 정보 부정확

MySQL의 옵티마이저는 통계 정보를 기반으로 실행 계획을 결정한다. 통계 정보가 오래된 경우 인덱스가 무시될 수 있다.

-- 해결법: ANALYZE TABLE로 통계 갱신
ANALYZE TABLE users;

⚙️ 6. LIMIT + OFFSET 조합

LIMIT OFFSET과 ORDER BY가 결합되면, 인덱스가 제대로 활용되지 않는 경우가 많다.

-- 해결법: 커버링 인덱스 고려, 서브쿼리 활용
SELECT * FROM (
  SELECT id FROM users ORDER BY created_at LIMIT 1000, 20
) AS temp
JOIN users USING (id);

🧱 7. 인덱스 컬럼 순서와 WHERE 조건 순서 불일치

복합 인덱스의 순서가 WHERE 조건과 일치하지 않으면 인덱스를 사용할 수 없다.

-- INDEX(name, email)
SELECT * FROM users WHERE email = 'a@b.com'; -- 인덱스 미사용
SELECT * FROM users WHERE name = '홍길동'; -- 인덱스 사용

🛠️ 인덱스 무시 여부 확인: EXPLAIN 필수

EXPLAIN SELECT * FROM users WHERE name LIKE 'kim%';

type, key, rows 등의 정보를 확인하면 인덱스 사용 여부를 파악할 수 있다. ALL이 표시되면 풀 테이블 스캔 중이므로 인덱스가 무시된 것이다.

✅ 실무에서의 팁

  • 복합 인덱스 설계 시 WHERE절 조건의 자주 사용되는 순서를 고려해야 한다
  • 정기적으로 ANALYZE TABLE을 통해 통계를 최신 상태로 유지해야 한다
  • EXPLAIN, SHOW INDEX, SHOW CREATE TABLE을 주기적으로 분석하여 인덱스 효율성을 점검해야 한다

🔗 참고 공식문서

https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html

반응형