
처음에는 몰랐지만, 데이터가 점점 많아지며 실서비스에서 페이지 로딩 속도가 체감될 정도로 느려지기 시작...!!
이제는 더 이상 안되겠다 싶어 MySQL 슬로우 쿼리 로그를 분석하게 되었다.
이번 포스팅에서는 슬로우 쿼리 분석 도구인 pt-query-digest 를 활용해 문제를 진단하고,
쿼리 개선 및 인덱스 튜닝을 통해 성능을 최적화한 과정을 공유한다.
✅ 1. 문제 인지: 느려진 페이지 응답 시간
운영 중 다음과 같은 문제가 포착되었다.
- 특정 페이지에서 데이터 조회 시간이 3초 이상 소요
- DB 조회 쿼리 성능 병목 가능성 의심
- Azure 포털에서 슬로우 쿼리 로그 확인 가능
👉 참고: Azure MySQL 슬로우 쿼리 진단 가이드
쿼리 성능 문제 해결 - Azure Database for MySQL - Flexible Server
Azure Database for MySQL - 유연한 서버에서 쿼리 성능 문제를 해결하는 방법을 알아봅니다.
learn.microsoft.com
🛠️ 2. 슬로우 쿼리 로그 수집
Azure Database for MySQL에서 다음과 같은 방식으로 슬로우 쿼리 로그를 확인할 수 있다.
- Azure Portal → 해당 MySQL → Logs & Metrics → 슬로우 로그 다운로드
🔍 3. 슬로우 쿼리 분석 도구: pt-query-digest
🔹 Percona Toolkit 설치 (macOS 기준)
brew install percona-toolkit
설치 완료 후 확인:
pt-query-digest --version
🔹 슬로우 쿼리 분석 실행
pt-query-digest mysql-slow-*.log > report.txt
- Query_time, Rows_examined, Fingerprint 기준으로 상위 쿼리 우선 분석
📌 4. 대표 슬로우 쿼리 분석 예시
슬로우 쿼리 중 하나는 다음과 같았다.
select
p1.id, p2.id, c.biz_name, ...
from
product_request p1
left join ...
where
p1.product_status = 'CONFIRMED'
and p1.created_at between ...
분석 결과
- Query_time: 4.331초
- Rows_examined: 235,660
- 문제 원인: product_status, created_at 필드에 적절한 복합 인덱스 없음
📋 5. EXPLAIN을 통한 쿼리 구조 분석
EXPLAIN으로 각 쿼리의 실행 계획을 확인해 병목 원인을 더 명확히 파악했다.
EXPLAIN
SELECT ...
FROM product_request
WHERE product_status = 'CONFIRMED'
AND created_at BETWEEN ...
🔍 주요 분석 포인트
| 항목 | 설명 |
| type | ALL이면 풀 테이블 스캔 (비효율) |
| rows | 예측 스캔 row 수, 값이 클수록 느림 |
| key | 사용된 인덱스 이름 |
| Extra | Using temporary, Using filesort 등 등장 시 개선 여지 |
⚙️ 6. 쿼리 개선 및 인덱스 튜닝
✅ 인덱스 추가
ALTER TABLE product_request
ADD INDEX idx_status_created (scm_product_status, created_at);
📈 7. 전반적인 성능 개선 결과
| 구분 | 개선 전 | 개선 후 |
| 평균 쿼리 시간 | 3~4초 | 100~200ms |
| 페이지 로딩 시간 | 느림 | 쾌적 |
✍️ 느낀 점 & 다음 계획
- 슬로우 쿼리 로그 + EXPLAIN 만으로도 충분한 성능 튜닝 가능!
- 병목 쿼리는 반드시 정기적으로 점검 필요
'DB' 카테고리의 다른 글
| 인덱스(Index)의 원리와 성능 최적화 방법 (0) | 2024.09.26 |
|---|