EXPLAIN 사용
EXPLAIN 결과 컬럼
- 테이블의 어느 곳에 인덱스를 추가해야 성능이 향상되는지 알 수 있음.
- 옵티마이저가 최적의 순서로 테이블을 조인할 수 있는 지 여부 검사.
EXPLAIN 결과 컬럼
- id : 쿼리 안의 SELECT 순차 번호
- select_type : SELECT 타입
SIMPLE - 단순 SELECT (UNION 이나 서브쿼리를 사용하지 않음)
PRIMARY - 가장 외곽의 SELECT
UNION - UNION의 두번째 혹은 그 이후의 SELECT
DEPENDENT UNION - UNION의 두번째 혹은 그 이후의 SELECT, 외곽 쿼리에 의존적
UNION RESULT - UNION의 결과
SUBQUERY - 서브쿼리의 첫번째 SELECT
DEPENDENT SUBQUERY - 서브쿼리의 첫번째 SELECT, 외곽 쿼리에 의존적
DERIVED - SELECT로 추출된 테이블 (FROM 절의 서브쿼리)
UNCACHEABLE SUBQUERY - 결과가 캐시될 수 없고 외곽 쿼리의 각 행에 대해 재평가되어야만 하는 서브쿼리
UNCACHEABLE UNION - 캐시될 수 없는 서브쿼리에 속하는 UNION의 두번째 혹은 그 이후의 SELECT - table : 결과 열이 참조하는 테이블
- type : 조인(join) 타입
system - 하나의 열만 가지는 테이블(=시스템 테이블)
const - primary key나 unique 인덱스의 모든 부분을 상수값과 비교. 하나의 열만 존재하기 때문에 매우 빠름.
SELECT * FROM tbl_name WHERE primary_key=1;
eq_ref - = 연산자를 사용해서 비교되는 인덱스된 컬럼용으로 사용.
SELECT * FROM ref_table, other_table WHERE ref_table.key_column = other_table.column;
ref - = 또는 <=> 연산자를 사용해서 비교되는 인덱스된 컬럼에 대해 사용
SELECT * FROM ref_table WHERE key_column = expr;
ref_or_null - ref 와 유사하지만, null 값을 가지고 있는 열에 대해서도 검색. 서브 쿼리를 해석할 때 자주 사용
SELECT * FROM ref_table WHERE key_column = expr OR key_column IS NULL;
index_merge - 인덱스 병합 최적화가 사용되었음.
unique_subquery - IN 서브 쿼리 (subqueries)에 대해서 ref를 대체하는 인덱스 lookup 함수임.
index_subquery - unique_subquery와 유사하지만 non-unique 인덱스에 대해서도 동작함.
range - 주어진 범위에 들어 있는 열만을 추출하며, 열 선택은 인덱스를 사용함. 키 컬럼이 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, 또는 IN 연산자를 사용하는 상수 (constant)와 비교할 때 사용할 수 있음.
index - ALL과 동일하지만 인덱스 트리만을 스캔함.
ALL - 전체 테이블 스캔. - possible_keys : 테이블에서 열을 찾기 위해 선택한 인덱스.
- key : 실제 사용할 예정인 키(인덱스)
- key_len : MySQL이 사용하기로 결정한 키의 길이.
- ref : 테이블에서 열을 선택하기 위해 인덱스를 어떤 컬럼 또는 상수(constant)와 비교하는지를 표시.
- rows : 쿼리를 실행하기 위해 조사해야 하는 열의 숫자를 가리킨다.
- filtered : 테이블 정의문이 필터링하는 테이블 열을 추정한 비율. rows는 조사된 열의 추정 숫자이며, rows × filtered / 100은 조인될 열의 숫자임. EXPLAIN EXTENDED를 사용하게 되면, 이 컬럼이 출력.
- Extra : 쿼리의 추가 정보
Distinct - 명확한 값을 찾게 되며 매칭되는 열을 찾게 되면 검색을 중단.
Full scan on NULL key - 인덱스 룩업(index-lookup) 접속을 할 수 없고 펄백(fallback) 방식으로 서브 쿼리 최적화를 할 때.
Impossible WHERE noticed after reading const tables - 모든 const(system) 테이블 값을 읽었으며, WHERE 구문이 항상 거짓(false)일 때.
No table - FROM 구문이 없거나, FROM DUAL 구문이 있을 때.
Not exists - LEFT JOIN 최적화를 실행 했으며, 이 최적화와 매치되는 열을 찾은 후에는 이전 열 조합 검색 중단.
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
range checked for each record (index map: N) : 사용하기에 좋은 인덱스를 찾지 못했으나, 컬럼값을 찾고 난 후에는 사용할만한 인덱스를 찾았음.
Select tables optimized away : 인덱스, 또는 MyISAM용 COUNT(*)을 사용하되 GROUP BY 구문은 사용하지 않은 채로 처리된 집단 함수(MIN(), MAX())만을 가지고 있음.
Using filesort : 정렬(sort)은 조인(join) 타입과 정렬 키 and WHERE 구문과 매치가 되는 모든 열에 대한 열 포인터(pointer)를 사용해서 모든 열에 걸쳐 진행.
Using index : 인덱스 트리에 있는 정보만을 가지고 테이블에서 컬럼 정보를 추출.
Using join cache : 테이블을 부분적으로 읽어온 후에, 읽어 온 열을 사용해서 조인을 실행.
Using temporary : 결과를 저장할 임시 테이블을 하나 생성해야 함. GROUP BY and ORDER BY 구문을 가지고 있는 경우 나타남.
Using where : 테이블에 대한 열 매치 (match) 또는 클라이언트에 보내지는 열을 제한하기 위해 사용.
Using sort_union(...), Using union(...), Using intersect(...) : 인덱스 스캔이 어떻게 index_merge 조인 타입과 병합(merge)이 되는지 출력.
Using index for group-by : 실제 테이블을 추가 접속하지 않은 채로 GROUP BY 또는 DISTINCT 쿼리의 모든 컬럼을 추출할 때 사용할 수 있는 인덱스.
Using where with pushed condition : 테이블을 추가 검색하지 않고도, GROUP BY 또는 DISTINCT 쿼리의 모든 컬럼을 추출하기 위해 사용될 인덱스를 찾았음.
WRITTEN BY
- 손가락귀신
정신 못차리면, 벌 받는다.
,