DB

[MySQL] 실무 예제로 배우는 느린 쿼리 튜닝 실습 (EXPLAIN + INDEX 활용)

인생아 2025. 7. 4. 10:23
반응형

실제 운영환경에서 느린 쿼리(Slow Query)는 곧 서비스 지연으로 이어진다. 단순히 인덱스를 추가한다고 해결되지 않고, 실행계획(EXPLAIN)을 기반으로 구조적 원인 파악과 튜닝이 병행되어야 한다.

🏁 사전 준비: 테스트 테이블 생성

CREATE TABLE orders (
  id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT,
  status VARCHAR(20),
  created_at DATETIME,
  INDEX idx_user_id (user_id),
  INDEX idx_created_at (created_at)
);

그리고 약 10만 건 이상의 더미 데이터를 미리 삽입했다고 가정하자.

반응형

🐌 느린 쿼리 예제: 전체 테이블 스캔

SELECT * FROM orders
WHERE YEAR(created_at) = 2024
AND status = 'COMPLETED';

이 쿼리는 실행 속도가 매우 느리다. created_at에 인덱스가 있음에도 YEAR() 함수로 인해 인덱스가 무시된다.

🔎 EXPLAIN으로 실행계획 확인

EXPLAIN SELECT * FROM orders
WHERE YEAR(created_at) = 2024
AND status = 'COMPLETED';

Extra 항목에 Using where; Using temporary; Using filesort가 표시된다. 이는 인덱스 범위 검색이 안 되고, 정렬과 임시 테이블까지 발생했다는 의미다.

⚡ 성능 개선 방법 1: 함수 제거

SELECT * FROM orders
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31'
AND status = 'COMPLETED';

이렇게 바꾸면 created_at 인덱스를 정상적으로 사용할 수 있게 된다.

⚡ 성능 개선 방법 2: 복합 인덱스 추가

CREATE INDEX idx_status_created_at
ON orders(status, created_at);

WHERE 조건의 조합 순서에 맞춰 인덱스를 구성하면 복합 인덱스가 covering index로 작동할 수 있다.

반응형

🔍 튜닝 전후 실행계획 비교

항목 BEFORE AFTER
type ALL (Full Table Scan) range / ref
key NULL idx_status_created_at
rows 100,000 이상 5,000 이하
Extra Using filesort Using index

type이 ALL인 경우 테이블 전체를 순회하므로, ref, range, const 등으로 개선해야 한다.

⚠️ 실무 팁: 느려지는 대표 패턴

  • LIKE '%abc%' → 와일드카드 앞 위치는 인덱스 무시
  • OR 조건 다중 필드 → 조건별 인덱스 결합 어려움
  • JOIN 시 필터조건 누락 → 조인 후 필터링 발생
  • ORDER BY + LIMIT에 인덱스 미적용 → filesort 발생

🛠️ INDEX가 있어도 느릴 때 체크포인트

  1. WHERE에 함수 또는 연산이 있는가?
  2. WHERE 컬럼이 인덱스에 포함되어 있는가?
  3. 복합 조건 순서가 인덱스 순서와 일치하는가?
  4. SELECT * 사용으로 인해 Covering Index 무효화된 건 아닌가?
반응형

✅ 최적화된 쿼리 완성 예시

SELECT id, user_id, status, created_at
FROM orders
WHERE status = 'COMPLETED'
AND created_at BETWEEN '2024-01-01' AND '2024-12-31'
ORDER BY created_at DESC
LIMIT 50;

위 쿼리는 idx_status_created_at 복합 인덱스가 완전히 활용되며, 정렬, 필터링, 페이징까지 한 번에 처리할 수 있는 형태로 구성된다.

📌 정리 요약

항목 내용
느린 원인 WHERE 함수, 인덱스 미사용, SELECT *, ORDER BY filesort
개선 방법 WHERE 최적화, 복합 인덱스 구성, SELECT 컬럼 제한, LIMIT 최적화
EXPLAIN 활용 쿼리 실행방식 확인, rows/Extra 주의 깊게 보기

📎 참고 공식문서

MySQL Optimizing Queries:
https://dev.mysql.com/doc/refman/8.0/en/query-optimization.html

반응형