EXPLAIN 활용법
1. EXPLAIN 이란 mysql의 쿼리문이 DB에서 어떻게 처리가 되는지 실행계획을 알 수 있는 명령문이다.
2. EXPLAIN은 SELECT, DELETE, INSERT, REPLACE, UPDATE문과 함께 작동한다. 하지만 활용도면에서는 SELECT쿼리문에서 9할 이상 차지하는 것 같다.
-- 실행 방법
EXPLAIN SELECT * FROM TB_PRODUCT;
EXPLAIN
UPDATE TB_PRODUCT
SET
PRODUCT_NAME = '상품명 업데이트'
WHERE
PRODUCT_NO = 1;
3. EXPLAIN 칼럼
- id : 쿼리문 안에 있는 각 select문에 대한 순차 식별자로 id안의 숫자 차례대로 select문이 실행된다.
- select_type : select문의 유형이다.
ㄴ SIMPLE : union 또는 sub query 등이 없는 기본 select 쿼리
ㄴ PRIMARY : union 또는 sub query 등을 사용하는 경우 첫 번째 select 쿼리
ㄴ UNION : union에서 두 번째 이상의 select 쿼리
ㄴ DEPENDENT_UNION : UNION이나 UNION ALL로 결합된 단위 쿼리가 외부의 영향에 받는 것을 의미한다.
ㄴ UNION_RESULT : union의 결과
ㄴ SUBQUERY : sub query의 첫 번째 select 쿼리
ㄴ DEPENDENT_SUBQUERY : 서브 쿼리가 바깥쪽(Outer) SELECT 쿼리에서 정의된 칼럼을 사용하는 경우를 DEPENDENT SUBQUERY라고 표현한다.
ㄴ DERIVED : 서브 쿼리가 from 절에서 사용된 경우 DERIVED로 표시된다. DERIVED는 단위 SELECT 쿼리의 실행
결과를 메모리나 디스크에 임시 테이블을 생성하는 것을 의미한다. DERIVED로 생성되는 임시 테이블을 파생
테이블이라고도 한다. FROM 절에 사용된 서브 쿼리는 제대로 최적화되지 못할 때가 대부분이다. 파생 테이블에는
인덱스가 전혀 없으므로 다른 테이블과 조인할 때 성능상 불리할 때가 많다. 가능하다면 DERIVED 형태의 실행
계획을 조인으로 해결할 수 있도록 바꾸는 것이 좋다.
ㄴ UNCACHEABLE SUBQUERY : 쿼리에서 from 절 이외의 부분에서 사용된 서브 쿼리는 mysql 옵티마이저가
캐싱하여 재사용이 될 수 있도록 유도하는데 이러한 캐시 기능을 사용할 수 없는 경우이다. 이러한 경우에는 사용자
변수를 제거하거나 다른 함수로 대체해서 사용하는 것을 검토하는 것이 좋다.
ㄴ UNCACHEABLE UNION : UNION과 동일하지만 공급되는 모든 값에 대하여 UNION 쿼리를 재처리한다.
- table : 결과 열이 참조되는 테이블을 표시한다.
- partitions : 테이블의 파티션중 어떤 파티션을 사용했는지 등의 정보를 표시한다.
- type : 조인(join)의 타입.
ㄴ system : 하나의 행만 가지고 있다. const조인 유형의 특별한 경우이다.
ㄴ const : 테이블은 적어도 하나의 매칭테이블을 가지고 있는데, 쿼리가 시작되는 시점에서 이 테이블을 읽게 된다.
여기에는 하나의 열만이 존재하기 때문에, 이 열에 있는 컬럼에서 얻는 값은 나머지 옵티마이저에 의해
상수(constant)로 인식될 수 있다. const 테이블은 한번 밖에 읽혀지지 않기 때문에 매우 빠르다.
ㄴ eq_ref : 이전 테이블로부터 각 열을 조합 (combination)하기 위해서 이 테이블의 열을 하나읽는다.
system 및 const 타입과는 달리, 이것이 가장 최선의 가능 조인 (join) 타입이다. 이것은 조인 (join)에 의해 인덱스의
모든 부분이 사용될 때 쓰이게 되며, 이때 인덱스는 PRIMARY KEY 또는 UNIQUE 인덱스가 된다. eq_ref는
= 연산자를 사용해서 비교되는 인덱스된 컬럼용으로 사용될 수 있다. 비교 값은 이 테이블 전에 읽었던 테이블에서 컬럼을 사용한 수식 또는 상수 (constant)가 될 수 있다. 아래의 예제에서 보면, MySQL은 ref_table를 처리하기
위해서 eq_ref 조인 (join)을 사용하고 있다.
ㄴ ref : 이전 테이블에서 읽어온 각각의 열을 조합하기 위해 이 테이블에서 매칭되는 인덱스 값을 가진 모든 열을
읽어온다. 만일 조인 (join)이 키의 좌측 끝(leftmost) 접두사 만을 사용하거나 또는 키 값이 PRIMARY KEY
또는 UNIQUE 인덱스가 아니라면 (달리 말하면, 만일 조인 (join)이 키 값을 기반으로 한 단일 (single) 열을 선택하지
않는다면), ref가 사용된다. 만일 사용된 키가 적은 수의 열에 대해서만 매치가 된다면, 그것은 좋은 조인 (join) 타입인
것이다. ref는 = 또는 <=> 연산자를 사용해서 비교되는 인덱스된 컬럼에 대해 사용될 수 있다.
ㄴ ref_or_null : 이 조인 (join) 타입은 ref과 유사하지만, MySQL이 NULL 값을 가지고 있는 열에 대해서도 검색을
한다는 점에서 차이가 있다. 이 조인 (join) 타입 최적화는 서브 쿼리(subqueries)를 해석할 때 자주 사용된다. 아래의
예제에서 보면, MySQL은 ref_table처리 과정에서 ref_or_null 조인 (join)을 사용하고 있다.
ㄴ index_merge : 이 조인 (join) 타입은 인덱스 병합 최적화가 사용되었음을 나타낸다. 이 경우에, 결과 열에
있는 key 컬럼은 사용된 인덱스 리스트를 가지고 있고, key_len는 사용된 인덱스에 대해서 가장 긴 키 부분의
리스트를 가지고 있다.
ㄴ unique_subquery : 이 타입은 아래 형태의 IN 서브 쿼리 (subqueries)에 대해서 ref를 대체한다.
ㄴ index_subquery : 이것은 unique_subquery와 유사한 조인 (join) 타입이다. 이것은 IN 서브 쿼리(subqueries)를
대체하지만, 아래 형태의 서브 쿼리 (subquery)에 있는 논-유니크(non-unique)인덱스에 대해서도 동작을 한다.
ㄴ range : 주어진 범위에 들어 있는 열만을 추출하며, 열 선택은 인덱스를 사용한다. 결과 열에 있는 key 컬럼은
어떤 인덱스가 사용되었는지를 가리킨다. key_len은 사용된 키에서 가장 긴 부분을 가진다. ref 컬럼은 이 타입에
대해서는 NULL 값이 된다. range는 키 컬럼이 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, 또는 IN 연산자를
사용하는 상수 (constant)와 비교할 때 사용될 수 있다
SELECT * FROM tbl_name WHERE key_column = 10;
SELECT * FROM tbl_name WHERE key_column BETWEEN 10 AMD 20;
SELECT * FROM tbl_name WHERE key_column IN (10,20,30);
SELECT * FROM tbl_name WHERE key_part1= 10 AND key_part2 IN (10,20,30);
ㄴ index : 이 조인 (join) 타입은 ALL과 동일하지만, 인덱스 트리 (index tree)만을 스캔한다는 점에서 다르다.
일반적으로, 보통의 인덱스 파일이 데이터 파일보다 작기 때문에, 이것은 ALL 보다는 빠르게 동작한다.
MySQL은 쿼리가 단일 인덱스의 일부분인 컬럼만을 사용할 때 이 조인 (join) 타입을 사용한다.
ㄴ ALL : 이전 테이블에서 읽어온 각각의 열을 조합하기 위해 전체 테이블 스캔을 실행한다. 테이블이 const가
표시되지 않은 첫 번째 테이블이고, 다른 모든 경우에 있어서 매우 좋지 않은 경우라면, 이것은 그리 좋은 경우가
아니다. 일반적인 경우에는, 이전 테이블에서 가져온 상수(constant) 값 또는 컬럼 값을 사용해서 테이블 열을
추출하는 인덱스를 추가하면 ALL을 피할 수가 있다.
- possible_keys : 테이블에서 열을 찾기 위해 mysql이 선택한 인덱스를 가리킨다. 이 칼럼은 EXPLAIN의 결과에서
나타나는 테이블 순서와는 완전히 별개의 순서가 된다. 이는 possible_keys의 일부 키가 테이블 순서를 만드는 과정에서 사용되지 않을 수도 있음을 의미한다.
- key : mysql이 실제로 사용하기로한 index를 나타낸다. possible_keys 인덱스 중 하나를 사용하여 행을 찾으려면 해당 인덱스가 key값으로 나열된다.
- key_len : mysql이 사용하기로 결정한 key의 길이를 나타낸다. key 값이 NULL이면 key_len도 NULL값이 된다.
- ref : 테이블에서 열을 선택하기 위해 key 안에 명명되어 있는 인덱스를 어떤 컬럼 또는 상수와 비교하는지를 보여준다.
- rows : mysql이 쿼리를 실행하기 위해 조사해야 하는 열의 숫자를 가리킨다.
- Extra : mysql이 쿼리를 어떻게 해석하는지에 관한 추가적인 정보를 제공한다.
'Database > ----- Mysql -----' 카테고리의 다른 글
[MYSQL] 컬럼안에 특정문자 개수 세는법 (0) | 2021.10.18 |
---|---|
[MYSQL] MySQL 쓰면서 하지 말아야 할 것 17가지 (0) | 2017.11.10 |