MySQL :: MySQL 8.4 Reference Manual :: 7.4.5 The Slow Query Log
7.4.5 The Slow Query Log The slow query log consists of SQL statements that take more than long_query_time seconds to execute and require at least min_examined_row_limit rows to be examined. The slow query log can be used to find queries that take a long
dev.mysql.com
갑작스러운 트래픽 폭증으로 인해 데이터베이스(DB)에 부하가 걸려 서비스 장애를 경험해 본 적 있으신가요? 최근 사내에서 특정 이벤트 시간대에 접속자가 과도하게 몰리면서 DB 락(Deadlock) 현상이 발생했고, 서비스가 일시적으로 마비되는 심각한 상황을 겪었습니다. 이 문제의 핵심 원인을 찾고 해결하는 과정에서 Slow Query 분석이 결정적인 역할을 했는데요.
오늘은 실제 운영 환경에서 발생한 DB 부하 상황을 Slow Query 로그를 통해 진단하고, 이를 효과적으로 해결했던 쿼리 튜닝 및 사용자 분산 전략에 대해 자세히 공유해 드리겠습니다.
🚨 문제 진단: Slow Query 로그로 원인 파악하기
DB 부하의 징후는 다양하지만, 가장 확실한 원인 중 하나는 **오래 걸리는 쿼리(Slow Query)**입니다.
1. Slow Query란?
Slow Query는 데이터베이스에서 설정된 기준 시간(Threshold)보다 실행 시간이 오래 걸리는 SQL 쿼리를 말합니다. 예를 들어, MySQL에서 설정된 long_query_time이 1초라면, 1초 이상 걸리는 모든 쿼리가 Slow Query 로그에 기록됩니다.
2. 진단 과정: mysql-slow.log 확인

장애 발생 직후, 저희는 MySQL의 slowquery.log 파일을 확인했습니다. 이 로그 파일에는 다음 핵심 정보들이 기록되어 있습니다.
- 실행 시간 (Time taken): 해당 쿼리가 실행되는 데 몇 초가 걸렸는지 (예: Query_time: 5.432101)
- 어떤 쿼리가 수행되었는지: 실행된 SQL 구문 전체
- 실행 시점: 언제 이 쿼리가 실행되었는지
로그 분석 결과, 트래픽이 몰리는 순간 특정 데이터 조회/업데이트 쿼리가 수 초씩 걸리면서 다른 모든 쿼리의 처리를 지연시키고, 결국 DB 락을 유발했다는 사실을 확인할 수 있었습니다.
✅ Slow Query 해결 방안 및 최적화 전략
Slow Query로 인한 DB 부하를 해결을 위해 크게 DB 내부 최적화와 외부 부하 분산이라는 두 가지 접근 방식을 취했습니다.
1. 핵심 해결책: 쿼리 튜닝 (Query Tuning)
Slow Query의 가장 근본적인 해결책은 비효율적인 쿼리를 효율적으로 개선하는 것입니다.
| 튜닝 항목 | 주요 내용 |
| 인덱스(Index) 최적화 | WHERE 절이나 JOIN 조건에 사용되는 컬럼에 적절한 인덱스가 설정되어 있는지 확인하고 추가합니다. 인덱스는 책의 목차와 같아서, DB가 전체 테이블을 스캔하지 않고도 빠르게 데이터를 찾게 해줍니다. |
| EXPLAIN 분석 | MySQL의 EXPLAIN 명령어를 사용하여 쿼리 실행 계획을 분석합니다. Full Table Scan이 발생하는지, 비효율적인 JOIN 방식은 없는지 등을 파악하여 튜닝 방향을 설정합니다. |
| 불필요한 데이터 제거 | SELECT * 대신 필요한 컬럼만 조회하고, LIMIT을 사용하여 가져오는 데이터 양을 최소화합니다. |
2. 사용자 분산을 위한 알림 발송 최적화
Slow Query의 근본적인 원인을 해결했더라도, 순간적인 대규모 트래픽이 유입되면 DB 부하는 또다시 발생할 수 있습니다. 따라서 특정 시간에 집중되는 사용자 요청을 분산시키는 전략이 필요했습니다.
저희는 이벤트 알림(푸시 및 카카오 알림) 발송을 동시 발송 대신 분산 발송 방식으로 변경했습니다.
- 이전 방식: 10만 명의 유저에게 알림을 거의 동시에 발송 → 10만 명의 유저가 거의 동시에 DB에 접속하여 부하 유발.
- 개선된 분산 발송 방식:
- 대상: 10만 명 유저
- 발송 정책: 1분당 1천 명씩 순차적으로 알림 발송.
- 결과: 사용자들의 접속 및 쿼리 요청을 100분(10만/1천)에 걸쳐 분산시킴으로써 순간적인 Peak 부하를 최소화했습니다. 발송 중에도 지속적인 DB 성능 모니터링을 통해 안정성을 확보했습니다.
💡 요약 및 마무리
Slow Query는 서비스의 성능과 안정성을 위협하는 가장 큰 요소입니다. 트래픽 Peak로 인한 DB 부하를 성공적으로 해결했던 우리의 경험은 다음과 같이 요약할 수 있습니다.
- 진단: slowquery.log를 주기적으로 확인하여 실행 시간이 긴 쿼리를 찾아냅니다.
- 내부 최적화: 쿼리 튜닝을 통해 인덱스를 최적화하고, 비효율적인 쿼리문을 개선합니다.
- 외부 분산: 트래픽이 예상되는 이벤트에 대해서는 사용자 분산 발송 전략을 적용하여 DB에 가해지는 순간적인 부하를 제어합니다.
지속적인 모니터링과 예방적 튜닝만이 안정적인 서비스를 유지하는 핵심입니다. 여러분의 서비스도 Slow Query로부터 안전하기를 바랍니다!
'IT > Backend | Database' 카테고리의 다른 글
| 대용량 데이터 삭제 • 옮기기 | 테이블 복제, 키변경, ALTER, RENAME (0) | 2025.04.08 |
|---|---|
| [DBeaver] 데이터 마이그레이션 | 다중 데이터베이스간 데이터 옮기기 (0) | 2025.03.19 |
| [MariaDB] 주석 작성 :: 공백 추가하기 (1) | 2024.12.13 |
| [postgreSql] 테이블 컬럼 정보 조회하기 :: table_name, column_name (0) | 2024.11.05 |