Explain은 select, delete, insert, replace, update 연산에 대해 수행 가능하다.
이 연산을 통해 MySQL은 옵티마이저로부터 어떻게 쿼리가 실행되는지 어떤 순서로 테이블들이 조인되는지를 볼 수 있다.
Explain 결과 해석
결과에 나오는 테이블은 MySQL 이 처리할 때 읽는 순서로 노출된다. 이 말은 MySQL이 첫 테이블로부터 row를 하나 읽고, 두번째 테이블로부터 이 row에 매핑된 row를 찾고, 세번째 테이블에서도 반복한다는 말이다. 모든 테이블이 처리되면, MySQL는 선택된 columns를 출력하고 일치하는 행이 더 있는 테이블을 찾을 때까지 테이블 list를 통해 백트래킹한다.
id
SQL 문이 수행되는 실행순서로, id 값이 작을수록 먼저 수행된거고 id 값이 같다면 두 테이블이 조인된 것.
조인이 수행된 이후에 서브쿼리가 수행되어서 아래처럼 조인 테이블은 모두 1, 서브쿼리 내 테이블은 2로 나옴.
select_type
SELECT문 유형.
주요 유형 소개
SIMPLE: union 이나 서브쿼리로 인식되는 것이 없는 경우에 나옴.
PRIMARY: 서브쿼리가 포함된 쿼리에서 첫번재 select 문에 표시되는 값. 서브쿼리를 감싸는 외부 쿼리이거나 UNION 이 포함된 쿼리의 첫번째 select 문에 표시됨.
SUBQUERY: 서브쿼리인데 바깥 쿼리에 영향받지 않고 독립적으로 수행 가능한 것 (DEPENDENT SUBQUERY와 비교 가능)
DEPENDENT SUBQUERY: 서브쿼리인데 바깥 쿼리에 영향을 받는 것
DERIVED : 파생테이블
DEPENDENT DERIVED: 다른 테이블에 영향 받는 파생 테이블
type
join type. 데이터를 어떻게 찾는지에 대한 정보고, 위에 적혀있을수록 성능이 좋고, 아래로 내려갈수록 성능 안 좋은 방식임.
system: system table 이라 1개 row만 가진 경우. const join type 에 속하는 것중 하나의 특별 케이스.
const: 고유 인덱스나 PK를 사용해서 단 1건의 데이터만 접근해서 얻은 경우. rows가 1로 나옴.
여기를 클릭하여 펼치기...
eq_ref: 조인 시 driving 테이블이 driven 테이블에서 고유 인덱스나 PK를 이용해 단 1건의 데이터만 접근한 경우
ref: 조인 시 driven 테이블에 접근하는 데이터 범위가 2개 이상일 경우
ref_or_null: IS NULL 구문 수행 시 인덱스를 활용했을 경우
range: 테이블 내 연속된 데이터를 조회한 경우. (비교연산이나 IS NULL, IN 등의 범위 스캔)
fulltext: FULLTEXT 인덱스를 활용한 경우
index_merge: 하나의 인덱스를 통해 데이터를 필터링하지 않고 여러 인덱스를 병합해서 데이터를 조회한 경우 (union 처럼 여러 인덱스를 사용해서 개별적으로 검색 후 합집합으로 결합)
ex) selectfrom users where age = 30; 이면 age 인덱스 하나로 가능하지만 select from users where age = 30 or city = 'Seoul'일 때 age,city 인덱스를 통해 결곽를 얻은 뒤 병합함.
index: 오직 인덱스 tree만 스캔되었을 때. (Extra 컬럼에도 Using Index라고 찍힘)
all: 테이블을 처음부터 끝가지 검색해서 풀스캔한 케이스
possible keys
옵티마이저가 SQL문을 최적화하기 위해 사용할 수 있는 인덱스 목록을 출력함.
다만 실제 사용한 인덱스가 아니라 사용할 수 있는 후보군을 보여주는 것.
key
옵티마이저가 SQL문을 최적화하기 위해 실제 사용한 PK 나 인덱스명
아무것도 사용하지 않았거나 비효율적인 인덱스를 사용했다면 SQL을 튜닝해야 한다.
key_len
사용한 인덱스의 바이트 수
ref
테이블 조인 시 어떤 조건으로 해당 테이블에 접근했는지에 대한 정보
rows
SQL 문을 수행하고자 접근하는 모든 데이터 row 수를 나타내는 항목. (예상값)
디스크에서 데이터 파일을 읽고 메모리에서 처리해야할 행 수를 예상하는 값임.
SQL문의 최종 결과 건수랑 비교해서 row가 크게 차이난다면 불필요하게 많은 데이터를 읽었다는 말이므로 SQL 튜닝이 필요하다고 해석할 수 있다.
filtered
어느 비율로 데이터를 제거했는지.
예를 들어 DB 엔진으로 100건의 데이터를 가져왔다면 이후 where 절의 emp_no between 1 and 10 조건으로 100건의 데이터가 10으로 필터링됨.