한 줄 정의
실행 계획은 옵티마이저가 통계 정보를 입력으로 세운 쿼리 처리 방법이며,
EXPLAIN으로 그 결정을 들여다보고 불합리한 부분을 찾아 더 나은 계획으로 유도하는 것이 튜닝의 출발점입니다.
쉽게 말하면
실행 계획은 내비게이션이 안내하는 경로 안내문 입니다.
- 내비(옵티마이저)는 지도와 교통 정보(통계) 를 보고 최적 경로를 정합니다 → Ch10-1 통계 정보
- 출발 전 그 경로를 미리 확인 하거나, 실제로 달려보고 시간을 잴 수 있습니다 → Ch10-2 실행 계획 확인
- 안내문의 각 항목(어느 길, 몇 km, 몇 분)을 읽고 해석 해야 어디가 막히는지 압니다 → Ch10-3 실행 계획 분석
내비를 못 읽으면 “왜 이 길로 가지?”에 답할 수 없습니다. 실행 계획을 읽을 줄 알아야 옵티마이저의 판단을 검증하고 교정할 수 있습니다.
왜 중요한가?
옵티마이저는 늘 좋은 계획을 만들지 못합니다. 관리자·개발자가 보완하려면 그 계획을 눈으로 봐야 합니다.
- “인덱스를 만들었는데 왜 안 타는가?” →
type·key칼럼으로 확인 - “데이터는 그대로인데 왜 느려졌는가?” → 통계·
rows·filtered변화 - “이 쿼리가 임시 테이블·정렬을 쓰는가?” →
Extra칼럼
실행 계획을 읽는 능력이 곧 진단 능력 입니다. 그래서 이 장은 MySQL 성능의 출발점입니다.
핵심 내용
10.1 통계 정보
| 서브노트 | 핵심 주제 |
|---|---|
| Ch10-1 통계 정보 | 영구적 테이블·인덱스 통계(innodb_*_stats), 히스토그램(싱글톤/높이 균형, 인덱스 다이브), 코스트 모델(server_cost/engine_cost) |
옵티마이저의 모든 판단은 통계라는 입력값 에서 나옵니다. 통계가 거짓말을 하면 1억 건 테이블을 10건으로 착각해 풀 스캔을 고릅니다. 8.0의 히스토그램 이 이 장의 가장 큰 변화입니다.
10.2 실행 계획 확인
| 서브노트 | 핵심 주제 |
|---|---|
| Ch10-2 실행 계획 확인 | EXPLAIN(테이블/TREE/JSON 포맷), EXPLAIN ANALYZE(실측 — actual time/rows/loops) |
EXPLAIN 은 예측, EXPLAIN ANALYZE 는 실측 입니다. 둘의 갭이 튜닝 포인트이며, 느린 쿼리는 먼저 EXPLAIN 으로 보고 고친 뒤 실측합니다.
10.3 실행 계획 분석
| 서브노트 | 핵심 주제 |
|---|---|
| Ch10-3 실행 계획 분석 | 12개 칼럼(id~Extra), type 12종(접근 방법), Extra 31개 항목 |
실행 계획의 핵심은 출력 포맷이 아니라 해석 입니다. type → key → Extra 순으로 읽으면 대부분의 진단이 끝납니다. 가장 헷갈리는 함정: type=index(인덱스 풀 스캔, 느림) ≠ Extra=Using index(커버링 인덱스, 빠름).
정리
실행 계획의 전체 흐름
flowchart TD STAT["통계 정보 (10.1)<br/>테이블·인덱스 통계 + 히스토그램 + 코스트 모델"] STAT --> OPT["옵티마이저<br/>비용 계산 → 최적 계획 선택"] OPT --> PLAN["실행 계획"] PLAN --> CHECK["확인 (10.2)<br/>EXPLAIN / EXPLAIN ANALYZE"] CHECK --> ANALYZE["분석 (10.3)<br/>12개 칼럼 해석"] ANALYZE --> TUNE["불합리 발견 → 튜닝<br/>인덱스·통계·쿼리 재작성"] TUNE -.->|재확인| CHECK
EXPLAIN 칼럼 한눈에
| 칼럼 | 한 줄 의미 | 튜닝 중요도 |
|---|---|---|
id | 단위 쿼리 식별자 (접근 순서 ≠) | 중 |
select_type | 쿼리 타입 (SIMPLE/SUBQUERY/DERIVED…) | 중 (DERIVED 주의) |
table | 대상 테이블/임시 테이블(<derivedN>) | 중 |
partitions | 접근 파티션 (프루닝 결과) | 하 |
type | 접근 방법 (const~ALL) | 상 |
possible_keys | 후보 인덱스 (무시 가능) | 하 |
key | 실제 선택 인덱스 | 상 |
key_len | 사용한 인덱스 바이트 수 | 중 |
ref | 비교 값 (func 주의) | 하 |
rows | 읽고 비교할 예측 건수 | 중 |
filtered | 필터 후 남는 비율(%) | 상 (조인) |
Extra | 내부 최적화·경고 (31종) | 상 |
내 생각
-
이 장은 “통계 → 계획 → 해석”이라는 한 줄 스토리로 묶어야 머리에 남습니다. 10.1·10.2·10.3을 따로 보면 파편적이지만, “옵티마이저는 통계로 계획을 세우고(10.1), 그 계획을 EXPLAIN으로 꺼내(10.2), 칼럼을 읽어 진단한다(10.3)“는 흐름으로 보면 하나의 이야기입니다.
-
튜닝의 8할은
type·key·Extra세 칼럼에서 끝납니다. 12개를 다 외우려 들면 압도되지만, 실무에서 먼저 보는 건 늘 이 셋입니다. 나머지는 이 셋에서 이상이 보일 때 보조로 봅니다. -
8.0의 진짜 주인공은 히스토그램입니다.
rows·filtered예측이 빗나가던 인덱스 없는 칼럼 문제를 정조준했고, 그 효과가 조인 순서에서 10배 차이로 드러납니다. 실행 계획을 읽다rows가 실제와 크게 다르면, 가장 먼저 의심할 것이 통계와 히스토그램입니다.
관련 개념
- Ch09 옵티마이저와 힌트 — 실행 계획을 만드는 주체(이 장은 그 결과를 검증)
- Ch08 인덱스 —
type·key·커버링 인덱스의 토대 - Ch04-1 MySQL 엔진 아키텍처 — 옵티마이저·실행 엔진·스토리지 엔진의 분리
출처
- Real MySQL 8.0 (1권), Ch10 실행 계획