Slow Query Log 기본: 수집 변수와 임계값, log_slow_extra 운영 설계
MySQL Slow Query Log의 기록 판정 순서, long_query_time 조정, log_slow_extra 활용과 Aurora MySQL 운영 차이를 정리한다.
Slow Query Log는 단순히 “느린 SQL을 저장하는 파일”이 아니다. 서버가 문장을 마친 뒤 실행 시간, 조사한 행 수, 문장 종류, 인덱스 사용 여부와 출력 대상을 차례로 평가하여 기록 여부를 결정하는 선별 수집 장치다. 따라서 로그를 켜는 것보다 중요한 일은 무엇을 느리다고 볼지, 어느 정도의 수집량을 감당할지, 기록된 문장을 어떤 근거로 우선순위화할지 설계하는 것이다.
임계값을 지나치게 높이면 사용자가 체감하는 지연을 놓치고, 너무 낮추면 로그 I/O와 분석 비용이 증가한다. log_queries_not_using_indexes를 무조건 켜면 작은 테이블의 정상적인 full scan까지 운영 신호를 덮을 수 있다. 반대로 log_slow_extra를 적절히 사용하면 단순 실행 시간 외에 Handler read, 정렬, 내부 임시 테이블 같은 문장 단위 단서를 확보할 수 있다.
이 글은 MySQL 8.0 이상을 기준으로 Slow Query Log의 판정 경로, 핵심 변수, 안전한 임계값 변경 절차와 log_slow_extra의 해석법을 설명한다. SQL 예제는 임시 MySQL 8.0 환경에서 실행 검증한다.
1. Slow Query Log가 기록을 결정하는 경로
Slow Query Log의 핵심 판정은 문장 실행이 끝난 뒤 이루어진다. 초기 lock 획득에 걸린 시간은 Query_time의 실행 시간 계산에 포함되지 않으며, 서버는 문장을 실행하고 lock을 해제한 뒤 로그를 쓴다. 그러므로 로그의 행 순서가 실제 실행 시작 순서와 일치한다고 가정하면 안 된다.
flowchart TD
A[SQL 문장 실행 완료] --> B{관리 문장인가?}
B -- 예 --> C{log_slow_admin_statements=ON?}
B -- 아니오 --> D{실행 시간이 long_query_time 이상인가?}
C -- 아니오 --> X[기록하지 않음]
C -- 예 --> D
D -- 예 --> E{Rows_examined가 min_examined_row_limit 이상인가?}
D -- 아니오 --> F{log_queries_not_using_indexes=ON이며\n인덱스 lookup을 사용하지 않았는가?}
F -- 아니오 --> X
F -- 예 --> E
E -- 아니오 --> X
E -- 예 --> G{비인덱스 문장 throttle 대상인가?}
G -- 억제 --> H[윈도 종료 시 집계 요약]
G -- 통과 --> I{slow_query_log와 log_output이 유효한가?}
I -- 아니오 --> X
I -- 예 --> J[FILE 또는 TABLE에 기록]
판정 순서를 운영 관점에서 풀면 다음과 같다.
ALTER TABLE,ANALYZE TABLE,CREATE INDEX같은 관리 문장은 기본적으로 제외된다. 필요하면log_slow_admin_statements를 활성화한다.- 일반 문장은 실행 시간이
long_query_time이상인지 평가한다. 또는log_queries_not_using_indexes=ON이고 row lookup에 인덱스를 사용하지 않았다면 시간 조건을 우회할 수 있다. - 두 경로 모두
min_examined_row_limit을 만족해야 한다. - 비인덱스 문장 수집은
log_throttle_queries_not_using_indexes의 분당 제한에 의해 억제될 수 있다. - 최종적으로
slow_query_log=ON이어야 하며log_output이FILE,TABLE또는 둘 다를 포함해야 한다.NONE이면 로그를 활성화해도 문장은 기록되지 않는다.
이 구조 때문에 slow_query_log=ON 하나만 확인해서는 충분하지 않다. “로그는 켜져 있는데 파일이 비어 있다”는 현상은 log_output=NONE, 너무 높은 long_query_time, 높은 min_examined_row_limit, 새 global 값이 기존 session에 반영되지 않은 경우 등에서 발생한다.
2. 핵심 변수와 역할
| 변수 | 역할 | 운영 해석 |
|---|---|---|
slow_query_log |
Slow Query Log 전체 활성화 | ON만으로 출력이 보장되지는 않는다. log_output도 확인한다. |
slow_query_log_file |
FILE 출력 경로 |
상대 경로는 일반적으로 data directory 기준이다. 로그 수집 에이전트의 읽기 범위도 확인한다. |
log_output |
FILE, TABLE, NONE 선택 |
log_slow_extra와 외부 로그 전송을 활용하려면 FILE이 중요하다. |
long_query_time |
느린 문장의 시간 임계값(초) | 최소 0, 기본값 10초이며 microsecond 단위 해상도로 설정할 수 있다. |
min_examined_row_limit |
최소 조사 행 수 | 아주 짧고 작은 문장을 걸러 수집량을 제어한다. |
log_slow_admin_statements |
느린 관리 문장 포함 | DDL·통계 갱신 작업의 지연을 조사할 때 유용하다. |
log_queries_not_using_indexes |
인덱스 lookup 미사용 문장 포함 | 실행 시간이 짧아도 기록될 수 있어 폭증 위험이 있다. |
log_throttle_queries_not_using_indexes |
비인덱스 문장 분당 기록 상한 | 0은 제한 없음이다. 양수는 60초 창에서 수집량을 제한한다. |
log_slow_extra |
FILE에 문장 단위 추가 카운터 기록 |
TABLE 출력에는 영향을 주지 않는다. |
log_timestamps |
파일 로그 timestamp의 시간대 | 기본 UTC를 운영 표준 시간대와 맞춰 해석한다. |
먼저 운영 서버의 실제 값을 한 번에 조회한다. SHOW VARIABLES LIKE ...를 여러 번 실행하는 대신 performance_schema.global_variables를 사용하면 설정 스냅샷을 일정한 형식으로 저장하기 쉽다.
SELECT VERSION() AS mysql_version;
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_variables
WHERE VARIABLE_NAME IN (
'slow_query_log',
'slow_query_log_file',
'log_output',
'long_query_time',
'min_examined_row_limit',
'log_slow_extra',
'log_slow_admin_statements',
'log_queries_not_using_indexes',
'log_throttle_queries_not_using_indexes',
'log_timestamps'
)
ORDER BY VARIABLE_NAME;
실행 결과(MySQL 8.0.x):
다음은 검증 출력에서 핵심 행만 발췌한 것이다.
mysql> SELECT VERSION() AS mysql_version;
+---------------+
| mysql_version |
+---------------+
| 8.0.46 |
+---------------+
1 row in set (0.00 sec)
mysql> SELECT VARIABLE_NAME, VARIABLE_VALUE
-> FROM performance_schema.global_variables
-> WHERE VARIABLE_NAME IN (...)
-> ORDER BY VARIABLE_NAME;
+----------------------------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+----------------------------------------+----------------+
| log_output | FILE |
| log_queries_not_using_indexes | OFF |
| log_slow_admin_statements | OFF |
| log_slow_extra | OFF |
| log_throttle_queries_not_using_indexes | 0 |
| log_timestamps | UTC |
| long_query_time | 10.000000 |
| min_examined_row_limit | 0 |
| slow_query_log | OFF |
+----------------------------------------+----------------+
이 결과는 현재 서버의 global 기준값이다. 접속별 long_query_time을 확인하려면 @@session.long_query_time도 별도로 조회해야 한다.
3. long_query_time은 단순한 숫자가 아니다
long_query_time은 초 단위지만 소수 값을 허용한다. 예를 들어 0.2는 200ms, 0.05는 50ms다. 중요한 점은 이 변수가 global과 session scope를 모두 가진다는 사실이다.
SELECT @@global.long_query_time AS global_before,
@@session.long_query_time AS session_before;
SET GLOBAL long_query_time = 0.250000;
SET SESSION long_query_time = 0.250000;
SELECT @@global.long_query_time AS global_after,
@@session.long_query_time AS session_after;
SET GLOBAL long_query_time = 10.000000;
SET SESSION long_query_time = 10.000000;
실행 결과(MySQL 8.0.x):
mysql> SELECT @@global.long_query_time AS global_before,
-> @@session.long_query_time AS session_before;
+---------------+----------------+
| global_before | session_before |
+---------------+----------------+
| 10.000000 | 10.000000 |
+---------------+----------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL long_query_time = 0.250000;
Query OK, 0 rows affected (0.00 sec)
mysql> SET SESSION long_query_time = 0.250000;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@global.long_query_time AS global_after,
-> @@session.long_query_time AS session_after;
+--------------+---------------+
| global_after | session_after |
+--------------+---------------+
| 0.250000 | 0.250000 |
+--------------+---------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL long_query_time = 10.000000;
Query OK, 0 rows affected (0.00 sec)
mysql> SET SESSION long_query_time = 10.000000;
Query OK, 0 rows affected (0.00 sec)
SET GLOBAL은 이후 새로 만들어지는 session의 초기값을 바꾼다. 이미 연결된 connection pool의 session 값은 자동으로 갱신되지 않는다. 따라서 임계값 변경 직후에도 애플리케이션의 기존 연결에서 이전 기준이 계속 사용될 수 있다. 긴 수명의 pool을 운영한다면 다음 중 하나를 선택한다.
- 새 연결에만 점진적으로 적용하고 전환 시간을 기록한다.
- 점검 창에서 connection pool을 순차 재생성한다.
- 제한된 진단 session에만
SET SESSION long_query_time=...을 적용한다. - 임시 변경 뒤에는 원래 값을 명시적으로 복구하고 변경 이력을 남긴다.
3.1 임계값 선정 방법
처음부터 10ms처럼 매우 낮은 값으로 전역 수집을 시작하지 않는다. 다음 순서가 안전하다.
- 서비스의 API 또는 batch별 응답 시간 목표를 확인한다.
- 현재
long_query_time에서 시간당 로그 건수와 byte 증가량을 측정한다. - 1초 → 500ms → 200ms처럼 단계적으로 낮추고 각 단계의 수집량을 비교한다.
- 상위 SQL digest와 총 실행 시간 기여도를 함께 본다. 한 번의 3초 SQL과 초당 수백 번 실행되는 80ms SQL은 다른 방식으로 우선순위화해야 한다.
- 조사 기간이 끝나면 기준값으로 되돌리거나, 새로운 기준을 parameter 관리 시스템에 영구 반영한다.
Slow Query Log는 임계값을 넘은 표본 집합이지 전체 workload가 아니다. long_query_time=1이면 900ms 문장은 아무리 자주 실행되어도 이 로그에 나타나지 않는다. 짧지만 빈번한 SQL은 Performance Schema의 statement summary, sys.statement_analysis, 애플리케이션 tracing과 함께 분석해야 한다.
4. 실제 TABLE 출력으로 기록 조건 확인하기
다음 예제는 임시 검증 인스턴스에서 Slow Query Log를 TABLE로 전환하고 80ms 대기 문장이 50ms 임계값을 넘어 기록되는지 확인한다. 운영 서버에서 mysql.slow_log를 비우면 기존 진단 기록이 삭제되므로 그대로 실행하면 안 된다. 이 예제의 TRUNCATE TABLE은 폐기 가능한 테스트 인스턴스에서만 사용한다.
SET GLOBAL slow_query_log = OFF;
SET GLOBAL log_output = 'TABLE';
TRUNCATE TABLE mysql.slow_log;
SET GLOBAL long_query_time = 0.050000;
SET SESSION long_query_time = 0.050000;
SET GLOBAL slow_query_log = ON;
SELECT SLEEP(0.08) AS slept;
SELECT query_time, rows_sent, rows_examined, db, sql_text
FROM mysql.slow_log
WHERE sql_text LIKE 'SELECT SLEEP(0.08)%'
ORDER BY start_time DESC
LIMIT 1;
SET GLOBAL slow_query_log = OFF;
SET GLOBAL long_query_time = 10.000000;
실행 결과(MySQL 8.0.x):
mysql> SET GLOBAL slow_query_log = OFF;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL log_output = 'TABLE';
Query OK, 0 rows affected (0.00 sec)
mysql> TRUNCATE TABLE mysql.slow_log;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL long_query_time = 0.050000;
Query OK, 0 rows affected (0.00 sec)
mysql> SET SESSION long_query_time = 0.050000;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL slow_query_log = ON;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT SLEEP(0.08) AS slept;
+-------+
| slept |
+-------+
| 0 |
+-------+
1 row in set (0.09 sec)
mysql> SELECT query_time, rows_sent, rows_examined, db, sql_text
-> FROM mysql.slow_log
-> WHERE sql_text LIKE 'SELECT SLEEP(0.08)%'
-> ORDER BY start_time DESC
-> LIMIT 1;
+-----------------+-----------+---------------+-----------------+-----------------------------+
| query_time | rows_sent | rows_examined | db | sql_text |
+-----------------+-----------+---------------+-----------------+-----------------------------+
| 00:00:00.080220 | 1 | 1 | mysql_tech_note | SELECT SLEEP(0.08) AS slept |
+-----------------+-----------+---------------+-----------------+-----------------------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL slow_query_log = OFF;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL long_query_time = 10.000000;
Query OK, 0 rows affected (0.00 sec)
이 검증에서 중요한 것은 query_time이 임계값보다 크고 sql_text가 의도한 문장과 일치하는지다. 실제 운영에서는 TABLE 로깅보다 파일 수집 파이프라인을 사용하는 경우가 많으며, TABLE 출력은 log_slow_extra의 추가 필드를 제공하지 않는다.
5. log_slow_extra가 추가하는 진단 정보
기본 FILE 출력은 주로 다음 값을 기록한다.
Query_time: 문장 실행 시간Lock_time: lock 획득 시간Rows_sent: client로 보낸 행 수Rows_examined: server layer가 조사한 행 수
MySQL 8.0.14부터 제공되는 log_slow_extra=ON은 FILE 출력에 문장 단위 추가 카운터를 기록한다. 주요 필드는 다음과 같이 묶어 해석할 수 있다.
| 범주 | 필드 | 읽는 방법 |
|---|---|---|
| 식별·종료 | Thread_id, Errno, Killed |
실패·강제 종료 여부와 다른 관측 데이터의 thread를 연결한다. |
| 네트워크 | Bytes_received, Bytes_sent |
큰 parameter 전송이나 과도한 결과 반환 가능성을 살핀다. |
| Handler 접근 | Read_first, Read_last, Read_key, Read_next, Read_prev, Read_rnd, Read_rnd_next |
key lookup, index 순차 읽기, 임의 읽기, scan 성격을 추정하는 단서다. |
| 정렬 | Sort_merge_passes, Sort_range_count, Sort_rows, Sort_scan_count |
정렬량과 merge pass 발생 여부를 확인한다. |
| 임시 테이블 | Created_tmp_tables, Created_tmp_disk_tables |
문장 하나가 만든 내부 임시 테이블과 disk 전환 단서를 본다. |
| 시간 경계 | Start, End |
동시 장애·배포·부하 이벤트와 문장 실행 구간을 맞춘다. |
이 값은 session 누적 status가 아니라 해당 문장에 대한 값이다. 예를 들어 Created_tmp_disk_tables=1이면 그 문장이 disk 기반 내부 임시 테이블을 하나 만들었다는 진단 단서가 된다. 다만 이것만으로 원인을 확정할 수는 없다. 실행 계획, projection 폭, GROUP BY·ORDER BY, TempTable 관련 설정을 함께 확인해야 한다.
log_slow_extra를 동적으로 켜고 FILE 대상 여부를 확인하는 최소 예제는 다음과 같다. 이 SQL은 변수 변경과 조회가 가능한지 검증하지만, 실제 파일 내용 확인은 mysqld가 실행되는 host 또는 로그 수집 계층에서 수행해야 한다.
SET GLOBAL log_output = 'FILE';
SET GLOBAL log_slow_extra = ON;
SELECT @@global.log_output AS log_output,
@@global.log_slow_extra AS log_slow_extra;
SET GLOBAL log_slow_extra = OFF;
실행 결과(MySQL 8.0.x):
mysql> SET GLOBAL log_output = 'FILE';
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL log_slow_extra = ON;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@global.log_output AS log_output,
-> @@global.log_slow_extra AS log_slow_extra;
+------------+----------------+
| log_output | log_slow_extra |
+------------+----------------+
| FILE | 1 |
+------------+----------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL log_slow_extra = OFF;
Query OK, 0 rows affected (0.00 sec)
운영 환경에서 활성화한 뒤에는 단순히 필드가 생겼는지만 확인하지 말고, 기존 parser가 확장된 필드 수와 혼합 형식을 처리하는지 점검한다. 한 파일 안에도 설정 변경 시점에 따라 기본 형식과 extra 형식이 함께 존재할 수 있다.
6. FILE과 TABLE 선택
6.1 FILE
FILE은 일반적으로 지속적인 수집과 외부 분석 도구 연동에 적합하다.
log_slow_extra의 추가 필드를 사용할 수 있다.- 파일 tailing agent, 중앙 로그 저장소,
mysqldumpslow같은 도구와 연결하기 쉽다. - 파일 회전, 보존 기간, filesystem 사용량과 수집 지연을 운영해야 한다.
log_timestamps=UTC라면 애플리케이션 local time과 비교할 때 시간대를 변환해야 한다.
대표적인 로컬 요약 명령은 다음과 같다. 실제 경로와 읽기 권한은 환경에 맞게 조정한다.
mysqldumpslow -s at -t 20 /var/lib/mysql/host-slow.log
-s at는 평균 query time 기준 정렬, -t 20은 상위 20개 표시를 뜻한다. 다만 SQL 정규화와 분산 환경 통합이 필요한 대규모 운영에서는 중앙 로그 분석이나 digest 기반 분석을 함께 사용한다.
6.2 TABLE
TABLE은 mysql.slow_log를 SQL로 즉시 조회할 수 있어 짧은 진단에 편리하다. 그러나 다음 한계가 있다.
log_slow_extra가 영향을 주지 않는다.- log table 자체의 크기와 정리 절차를 운영해야 한다.
- 높은 수집량에서는 DB 내부 쓰기 부담과 관리 복잡성이 커질 수 있다.
- 외부 로그 파이프라인이 FILE을 전제로 하면 수집되지 않는다.
FILE,TABLE을 동시에 지정할 수도 있지만, 두 대상의 저장 비용과 관리 부담이 함께 생긴다. 특별한 검증 목적이 아니라면 기본 수집 경로를 하나로 명확히 정하는 편이 좋다.
7. 비인덱스 문장 수집의 함정
log_queries_not_using_indexes=ON은 이름만 보면 “나쁜 SQL 탐지” 기능처럼 보이지만, 인덱스 미사용이 곧 비효율을 뜻하지는 않는다. 작은 lookup table의 full scan, 대부분의 행을 읽는 집계, optimizer가 비용상 full scan을 선택한 문장도 포함될 수 있다. 게다가 이 옵션을 켜면 long_query_time보다 빠른 문장도 기록 대상이 될 수 있다.
활성화가 필요하다면 다음 보호 장치를 같이 검토한다.
min_examined_row_limit으로 아주 작은 scan을 제외한다.log_throttle_queries_not_using_indexes를 양수로 설정해 분당 기록량을 제한한다.- 짧은 기간에만 켜고 파일 증가율과 억제 요약을 관찰한다.
- 기록된 문장을
EXPLAIN ANALYZE와 실제 실행 빈도로 재평가한다. - “인덱스 없음”만으로 신규 인덱스를 만들지 않는다. 쓰기 비용, buffer pool 점유, 중복 인덱스 여부를 함께 검토한다.
8. 운영 진단 절차
Slow Query Log가 비어 있거나 과도하게 증가할 때는 다음 순서로 확인한다.
- 활성 상태:
slow_query_log가ON인지 본다. - 출력 대상:
log_output이NONE이 아닌지, 외부 수집이 필요하면FILE인지 확인한다. - 임계값: global과 실제 application session의
long_query_time을 구분한다. - 행 필터:
min_examined_row_limit이 예상보다 높지 않은지 본다. - 비인덱스 경로: 관련 옵션과 throttle 값을 함께 확인한다.
- 파일·권한:
slow_query_log_file경로, filesystem 여유 공간, agent 읽기 권한을 확인한다. - 시간대:
log_timestamps와 dashboard의 시간대가 같은지 확인한다. - 분석기 호환성:
log_slow_extra활성화 후 parser가 혼합 형식을 처리하는지 확인한다. - 다른 관측점 대조: Performance Schema digest, 애플리케이션 trace, host 지표와 같은 시간 구간을 비교한다.
기록된 순서가 실행 시작 순서가 아닐 수 있다는 점도 중요하다. 장애 시점의 병렬 SQL 흐름을 복원하려면 Start·End, connection/thread 정보, 애플리케이션 request ID 또는 tracing을 함께 사용해야 한다.
9. Aurora MySQL에서의 차이
Aurora MySQL에서도 slow_query_log, long_query_time, log_output 등을 DB parameter group에서 관리한다. 그러나 자체 관리형 MySQL과 달리 host filesystem을 직접 운영하지 않으므로 로그 접근·보존·전송 경로를 AWS 관리 기능과 함께 설계해야 한다.
- Aurora MySQL의 Slow Query Log를 CloudWatch Logs로 내보내려면 cluster에서 slow query log export를 구성하고,
slow_query_log=1,log_output=FILE조건을 충족해야 한다. - AWS 문서 기준으로 Aurora MySQL의 general/slow query FILE 로그는 매시간 검사되며 24시간보다 오래된 파일이 삭제된다. 로그가 DB instance local storage의 15%를 넘는 경우 오래된 파일이 더 일찍 삭제될 수 있다. 장기 분석이 필요하면 CloudWatch Logs 등 외부 보존 경로가 필요하다.
TABLE을 사용하면mysql.slow_log를 조회할 수 있지만 CloudWatch Logs의 slow query export 경로와 맞지 않으며,log_slow_extra도 TABLE에는 추가 필드를 제공하지 않는다.- Aurora의 parameter family와 engine minor version에 따라 제공 변수와 적용 방식이 달라질 수 있다.
log_slow_extra를 전제로 수집기를 배포하기 전에 대상 cluster parameter group에서 변수 존재 여부와 적용 상태를 확인한다. - 장애 조치 후 writer instance가 바뀌어도 동일한 수집 정책이 유지되도록 instance별 수동 변경이 아니라 parameter group과 로그 export 설정을 구성 관리 대상으로 삼는다.
- Performance Insights 또는 Database Insights의 SQL 통계는 Slow Query Log를 대체하기보다 보완한다. 임계값 이하의 빈번한 문장과 DB load 기여도를 찾은 뒤, 로그 원문과 실행 계획으로 원인을 좁히는 방식이 효과적이다.
Aurora의 long_query_time을 낮출 때도 CloudWatch ingest 양과 보존 비용을 함께 예상해야 한다. 임계값 변경은 DB 부하뿐 아니라 로그 전송량, 검색 비용, 경보 noise를 바꾼다.
10. 흔한 오해와 주의사항
“Query_time이 길면 lock 대기 시간까지 모두 포함한다”
초기 lock 획득 시간은 Slow Query Log의 실행 시간 계산에 포함되지 않는다. lock 병목은 Performance Schema의 lock wait 정보, statement timing, transaction 상태를 같이 봐야 한다.
“로그 파일 순서가 실행 순서다”
문장 완료와 lock 해제 후 기록하므로 먼저 시작한 긴 문장이 뒤에 기록될 수 있다. 시간 경계와 tracing 정보 없이 순서만으로 인과관계를 단정하지 않는다.
“global 값을 바꾸면 모든 연결에 즉시 적용된다”
long_query_time 같은 session 상속 변수는 기존 연결에 이전 값이 남을 수 있다. connection pool 수명과 session 값을 확인한다.
“log_slow_extra를 켜면 mysql.slow_log에도 열이 늘어난다”
아니다. 추가 필드는 FILE 출력에만 기록되며 TABLE 출력은 영향을 받지 않는다.
“log_queries_not_using_indexes를 켜면 필요한 인덱스를 자동으로 찾을 수 있다”
이 옵션은 후보를 넓힐 뿐이다. full scan이 합리적인 문장도 포함되며, 인덱스 추가 판단에는 selectivity, 실행 빈도, 쓰기 증폭과 기존 인덱스 구성을 함께 봐야 한다.
“Slow Query Log만 있으면 전체 workload를 설명할 수 있다”
임계값 아래 문장은 보이지 않는다. 특히 자주 실행되는 짧은 SQL의 누적 부하는 Performance Schema digest와 workload 지표로 보완해야 한다.
11. 운영 체크리스트
도입 전
- 서비스별 응답 시간 목표와 초기
long_query_time -
FILE또는TABLE
설정 변경 시
-
log_queries_not_using_indexes -
log_slow_extra사용 시 출력 대상이FILE
운영 중
-
Rows_examined와Rows_sent -
Created_tmp_disk_tables
12. 결론
Slow Query Log의 품질은 활성화 여부보다 수집 조건의 설계에서 결정된다. long_query_time은 사용자가 체감하는 지연 목표와 수집량 사이의 경계이며, min_examined_row_limit, 비인덱스 수집 옵션과 throttle은 noise를 제어한다. log_slow_extra는 FILE 출력에 문장 단위 접근·정렬·임시 테이블 단서를 더해 원인 분석의 출발점을 풍부하게 만든다.
운영에서는 global과 session의 적용 시점, FILE과 TABLE의 차이, 파일 회전과 외부 보존, Aurora MySQL의 parameter group 및 CloudWatch export를 하나의 수집 파이프라인으로 다뤄야 한다. 다음 단계에서는 수집된 Slow Query Log를 digest로 묶고 실행 빈도·총 소요 시간·조사 행 수를 기준으로 튜닝 대상을 우선순위화하는 방법을 살펴볼 수 있다.