EXPLAIN은 SQL 쿼리의 실행 계획을 분석할 수 있게 해주는 명령어이다. 주로 SELECT, DELETE, UPDATE, INSERT, REPLACE 문 앞에 붙여 사용하며, 쿼리가
어떻게 실행될지, 어떤 인덱스를 사용할지, 어떤 순서로 테이블이 접근될지 등을 확인할 수 있다.
이를 통해 성능 병목을 파악하고 인덱스 최적화나 쿼리 구조 개션을 할 수 있다.
EXPLAIN
SELECT *
FROM users
WHERE age > 30;
EXPLAIN FORMAT = JSON
SELECT *
FROM users
WHERE age > 30;
EXPLAIN의 결과로 여러 개의 컬럼을 반하며 주요 컬럼은 다음과 같다.
| 컬럼 이름 | 설명 |
|---|---|
| id | 쿼리의 순서 또는 중첩된 쿼리의 단계 표시. 숫자가 클수록 먼저 실행됨. |
| select_type | 쿼리의 유형 (예: SIMPLE, PRIMARY, SUBQUERY, DERIVED 등) |
| table | 접근하는 테이블 이름 |
| type | 조인의 유형 또는 액세스 방식 (이 값이 중요!) |
| possible_keys | 사용할 수 있는 인덱스 목록 |
| key | 실제 사용된 인덱스 |
| key_len | 사용된 인덱스의 길이 |
| ref | 어떤 컬럼이나 상수가 인덱스를 통해 참조되는지 |
| rows | MySQL이 검사할 것으로 예상하는 행의 수 |
| Extra | 추가적인 정보 (Using index, Using where, Using temporary 등) |
이 컬럼은 조인의 효율성을 나타낸다. 아래로 갈수록 성능이 떨어진다.
system: 테이블에 1개의 row만 있음.const: 상수처럼 취급되는 row.eq_ref: 인덱스를 통해 정확히 하나의 row를 찾았다.ref: 인덱스를 통해 여러 row를 찾았다.range: 범위 검색(BETWEEN, >, <).index: 테이블 전체를 인덱스로 스캔.ALL: 테이블 전체를 스캔(풀 데이터 스캔, 성능 최악)ALL이 나올 경우 성능 이슈를 의심해보아야 한다.
possible_key는 있는데 key가 NULL이면 인덱스를 무시하고 있다는 의미이며 쿼리나 인덱스 개선이 필요하다.Using temporary나 Using filesort는 성능 이슈를 일으킬 수 있는 신호이다.EXPLAIN FORMAT=JSON을 사용하면 훨씬 상세한 실행 계획을 볼 수 있다.row의 수가 너무 적다면 FORCE INDEX (인덱스명)을 사용해서 인덱스 사용을 강제해서 테스트하면 된다.