테마
실행 계획 분석
EXPLAIN이 보여 주는 실행 계획(execution plan) 표를 읽는 법. 모든 칼럼을 다 볼 필요는 없다. type·key·rows·Extra 네 칼럼이 판단의 8할이다.
핵심 네 칼럼
| 칼럼 | 보는 것 | 좋은 신호 → 나쁜 신호 |
|---|---|---|
| type | 접근 방식 | 대체로 const·eq_ref·ref·range → index·ALL |
| key | 실제 사용 인덱스 | 의도한 인덱스 → NULL |
| rows | 예상 검사 행 수 | 적을수록 좋음 |
| Extra | 추가 작업 | Using index → filesort·temporary |
- type: 테이블을 어떻게 읽는지, 즉 접근 방식이다.
ALL은 테이블의 모든 행을 읽는 풀 테이블 스캔(full table scan),index는 인덱스 전체를 처음부터 끝까지 읽는 풀 인덱스 스캔(full index scan)이다.range는 인덱스로 범위를 탐색하고,ref는 유니크하지 않은 인덱스로 같은 값을 찾는다(비유니크 동등).eq_ref는 조인할 때 앞 테이블의 행마다 유니크한 키로 딱 한 건씩 매칭하고,const는 PK(Primary Key, 기본 키)나 유니크 인덱스(unique index)를 상수와 비교해 한 건만 읽는다. 이 순서는 경향일 뿐이고, 실제 비용·행 수·커버링 인덱스(covering index) 여부가 더 중요하다. - key vs possible_keys:
possible_keys는 쓸 수 있는 후보 인덱스,key는 실제로 고른 인덱스다. 후보는 있는데key가 NULL이거나 다른 인덱스라면 통계, 선택도(selectivity), 쿼리 작성 방식을 의심한다. - rows × filtered:
rows는 스캔 한 번당 검사할 것으로 예상한 행 수이고,filtered는 그중 테이블 조건을 통과할 것으로 예상한 비율(%)이다. 두 값을 곱하면 다음 조인 단계로 넘어갈 예상 행 수를 어림할 수 있다. 어디까지나 추정치이지 실측치가 아니다. - Extra:
Using index는 인덱스만 읽고 끝나는 커버링이라 반가운 신호다.Using filesort는 결과를 따로 정렬하는 파일소트(filesort),Using temporary는 중간 결과를 담는 임시 테이블(temporary table)을 쓴다는 뜻으로 둘 다 추가 작업이다.Using index condition은 ICP(Index Condition Pushdown, 인덱스 조건 푸시다운)가 적용돼 스토리지 엔진(storage engine) 안에서 조건을 먼저 걸렀다는 뜻이다.
나머지 칼럼 한 줄씩
- id·select_type:
id는 쿼리 블록(query block, SELECT 하나 단위)의 번호,select_type은 그 블록의 종류(SIMPLE·PRIMARY·SUBQUERY·DERIVED·UNION)다. 조인 순서와 서브쿼리(subquery) 구조를 파악하는 데 쓴다. - table·partitions: 접근하는 테이블과 파티션(partition)이다.
<derivedN>이면 FROM 절의 서브쿼리 결과로 만든 파생 테이블(derived table)이다. - key_len: 실제로 사용한 인덱스 키의 길이(바이트)다. 복합 인덱스에서 앞쪽 몇 칼럼까지 썼는지 보인다.
- ref: 인덱스와 비교한 대상(상수
const또는 다른 테이블의 칼럼)이다.ref: const면 상수 조건이다.
읽는 순서
- type에 ALL·index가 있나
- key가 의도대로인가 (possible_keys와 비교)
- rows × filtered가 감당되나
- Extra에
Using filesort·Using temporary가 있나 - id 순서대로 조인 흐름이 말이 되나
면접 포인트
- "EXPLAIN에서 뭘 봐요?" → type·key·rows·Extra. 순서대로 답한다.
- "ALL이 나왔어요" → 왜 인덱스를 못 탔는지 5가지(통계·함수·타입·선택도·읽기 비율)로.
- "rows와 filtered의 차이?" → 검사 예상 vs 통과율. 곱해서 본다.
