항상 DB 스키마를 짜고, 내가 사용하는 데이터에 따라 어떤 index를 걸어야 하는지 고민이 많다.
이것저것 index를 걸어보면서 항상 explain을 살펴보는데, 항상 이게 좋은건지 나쁜건지 파악이 안되는 경우가 많다. 그를 위해서 정리하는 explain 알아보기!
explain {실행할 select 쿼리}
형식으로 SQL를 실행해주면, 해당 실행할 쿼리가 MySQL에서 어떤 실행 계획을 가지고 쿼리를 실행하는지를 알려준다.
알려주는 정보로는, 실행할 때 몇개의 row를 보는지, 어떤 type으로 row를 조회하는지, 인덱스를 안타는지 등등... 여러가지 것들을 보여준다.
explain extended, explain partitions
명령을 통해 상세한 실행계획을 확인할 수도 있다.
explain을 실행하면 이렇게 표가 나오는데, 상황에 따라서 여러줄이 나올 수 있다.
(대개 join이 있으면 여러줄이 나옴) 실행 순서 순으로 위에서 아래로 나오는데, 상황에 따라 순서대로 표시되지 않을 수도 있다.
위쪽에 출력된 결과일수록 쿼리의 바깥 부분이거나 먼저 접근한 테이블.
id : 쿼리별로 부여되는 식별자값. 하나의 select 문에서 여러개의 테이블을 조인하면 여러 row가 나오지만, 하나의 id를 가지게 된다. (같은 쿼리니까)
select_type : 어떤 타입의 쿼리인지 나타내준다.
SIMPLE : 단순한 SELECT문일 때
PRIMARY: UNION, 서브 쿼리 포함된 SELECT 쿼리일 때 가장 바깥쪽 있는 쿼리를 표현할 때 사용.
UNION: UNION 이 있는 경우 첫째 이후 단위 select 쿼리들은 전부 UNION으로 표시된다. (UNION 첫째 단위 SELECT는 UNION 쿼리로 결합된 전체 집합의 select type이 표시된다.)
DEPENDENT: 내부의 쿼리가 외부의 정의된 값을 사용하면 이 키워드가 같이 붙는다.
→ 서브쿼리를 사용하게 되면 보통 서브쿼리 실행 후 외부쿼리 실행이 일반적. 하지만, 서브쿼리가 외부의 값을 참조하게 되면 절대 외부쿼리보다 먼저 실행될 수 없다. 따라서 이 키워드가 포함된 서브 쿼리는 비효율적인 경우가 많다.
UNION RESULT: UNION의 결과를 담아두는 테이블
SUBQUERY: 서부쿼리가 여러개를 말할 수 있지만 여기서는 from절 이외에서 사용되는 서브쿼리만을 의미한다.
→ FROM 절에 사용되는 서브쿼리는 DERIVED, 그 외는 SUBQUERY
type : MYSQL 서버가 각 테이블의 레코드를 어떤 방식으로 읽었는지
→ const, ref, range까지만 나온다고 하면 어느정도 쿼리 성능은 보장된다고 할 수 있다.