실행 계획
: 쿼리를 실행하기 전에 쿼리의 범위와 검색 방법 등을 미리 확인하는 것
- 쿼리
EXPLAIN <실행할 쿼리>
- 확인가능한 항목
: id
: select_type
: table
: type
: possible_keys
: key
: key_len
: ref
: rows
: extra
id
: SELECT 쿼리별 부여되는 식별자 값
: 여러 개의 테이블을 JOIN하면 JOIN되는 테이블의 개수만큼 실행계획 레코드가 출력되지만 id는 동일
select_type
: SELECT 쿼리가 어떤 타입의 쿼리인지 표시
- SIMPLE
: UNION이나 서브 쿼리를 사용하지 않는 단순한 SELECT 쿼리
- PRIMARY
: UNION이나 서브 쿼리가 포함된 SELECT 쿼리에서 실행 계획의 가장 바깥쪽의 단위 쿼리
- UNION
: UNION으로 결합되는 단위의 SELECT 쿼리에서 두 번째 이후의 SELECT 쿼리
- DEPENDENT UNION
: UNION이나 UNION ALL로 집합을 결합하는 쿼리에 표시
: 결합된 단위 쿼리가 외부의 영향을 받는 것을 의미
- UNION RESULT
: UNION 결과를 담아두는 테이블
- SUBQUERY
: FROM 절 이외에서 사용되는 서브 쿼리
: Nested Query (중첩된 쿼리. SELECT 되는 컬럼에 사용된 서브 쿼리)
: Sub Query (WHERE 절에 사용된 서브 쿼리)
: Dericed (파생 테이블. FROM절에 사용된 서브 쿼리)
- DEPENDENT SUBQUERY
: 바깥쪽 SELECT 쿼리에서 정의된 컬럼을 사용하는 서브 쿼리
- DRIVED
: 서브쿼리가 FROM 절에 사용된 경우 만들어지는 실행 계획
: 임시 테이블에서 파생된 테이블
: 해당 경우에는 JOIN을 사용하는 것을 권장
- UNCACHEABLE SUBQUERY
: 캐시가 불가능한 서브 쿼리
- UNCACHABLE UNION
: UNION 요소 중 특정 요소로 인해 캐시가 불가능한 경우
table
: MySQL의 실행 계획은 테이블 기준으로 표시됨
: 테이블 이름에 별칭이 부여된 경우 별칭이 표시됨
: <>으로 감싸져 있는 경우 임시 테이블을 지칭
: <>안에 표시되는 수자는 단위 SELECT id를 지칭
type
: MySQL 서버가 각 테이블의 레코드를 어떤 방식으로 읽었는지 의미
: 인덱스를 사용했는지, Full scan을 사용했는지 등
- system
: 레코드가 1건만 존재하는 테이블 또는 한건도 존재하지 않는 테이블을 참조하는 형태의 접근
: InnoDB 테이블에서는 나타나지 않음
- const
: 테이블 레코드 건수에 상관없이 쿼리가 PRIMARY KEY나 UNIQUE KEY 컬럼을 이용하는 WHERE 조건을 가지고
있으면서 반드시 1건을 반환하는 쿼리
- eq_ref
: 여러 테이블이 조인되는 쿼리의 실행 계획에서 표시
: 조인에서 처음이 읽은 테이블의 컬럼 값을 그 다음 읽어야할 테이블의 PK 컬럼의 검색 조건에 사용할 때
: 조인에서 두번째 이후에 읽은 테이블에서 레코드가 1건만 존재한다는 보장이 있어야 사용되는 접근 방법
- ref
: 인덱스 종류와 상관없이 동등 조건으로 검색 될 때
: 반환되는 레코드가 1건이 아닐 수 있으므로 const나 ep_ref에 비해 느림
- fulltext
: MySQL의 전문검색(Fulltext) 인덱스를 사용해 레코드를 읽는 접근 방법
- ref_of_null
: ref에서 NULL 비교가 추가된 형태
- unique_subquery
: WHERE 조건에서 사용될 수 있는 IN 형태의 쿼리를 위한 접근 방법
: 서브 쿼리에서 중복되지 않은 UNQUE한 값만 반환하는 경우
- index_subquery
: IN에서 서브 쿼리가 중복된 값을 반환할 수 있지만 중복된 값을 인덱스를 이용해 제거할 수 있을 때
- range
: index range scan 방법
: < 이나 >, IS NULL, BETWEEN, IN, LIKE 등 연산자 이용 시 나옴
: 어느 정도의 성능 보장 가능
- index_merge
: 2개 이상의 인덱스를 이용해 각각의 검색 결과를 만들어낸 후 결과를 병합하는 처리 방식
- index
: 인덱스에 대해 full scan을 하는 처리
- ALL
: 테이블에 대한 full scan을 하는 처리. 가장 비효율적인 방법
possible_keys
: MySQL OPTIMIZER가 최적의 실행 계획을 만들기 위해 후보로 선정했던 접근 방식에서 사용된 인덱스 목록
key
: 최종 선택된 실행 계획에서 사용하는 인덱스
key_len
: 쿼리를 처리하기 위해 다중 컬럼으로 구성된 인덱스에서 몇개의 컬럼까지 사용했는지 알려주는 값
: 인덱스의 각 레코드에서 몇 바이트까지 사용했는지 의미
ref
: 접근 방법이 ref면 참조 조건으로 어떤 값이 제공되었는지 의미
: 상수값이라면 const, 다른 테이블의 컬럼 값이라면 테이블명과 컬럼명을 표시
: 값 자체의 연산을 거친 경우 func
rows
: 실행계획의 효율성 판단을 위해 예측했던 레코드 건수
: 스토리지 엔진별로 갖고 있는 통계정보를 참조하여 OPTIMIZER가 산출해낸 예상 값
: 쿼리를 처리하기 위해 얼마나 많은 레코드를 읽고 체크해야하는지 의미
: LIMIT이 포함되는 쿼리가 반영되지 않아 부정확함
extra
: 쿼리 실행계횎에서 성능에 관련된 중요한 내용
- const row not found
: type 컬럼이 const인데 해당 테이블에 레코드가 1건도 없는 경우
- Distinct
: DINSTINCT를 처리하기 위해 꼭 필요한 항목만 조인했다는 의미
- Full scan in NULL key
: 컬럼의 값 중 NULL이 있으면 테이블을 full scan 하겠다는 의미
- Impossible HAVING
: 쿼리에 HAVING 절의 조건을 만족하는 레코드가 없는 경우
- Impossible WHERE
: 테이블 구조상 WHERE가 FALSE가 될 수 밖에 없음
- Impossible WHERE noticed after reading const table
: WHERE 조건에 일치하는 데이터가 없는 경우
- No matching min/max row
: MAX(), MIN()과 같은 집합 함수가 있는 쿼리의 조건절에 일치하는 레코드가 없는 경우
- no matching row in const table
: 조인에 사용된 테이블에서 const 방식으로 접근할 때 일치하는 레코드가 없는 경우
- No tables used
: FROM 절이 없는 쿼리 문장 실행 시
- Not exists
: NOT IN과 NOT EXISTS와 같은 안티 조인을 사용한 경우
: 레코드가 많을 경우 OUTER JOIN을 사용하는 것을 권장
- Range checked for each record
: 모든 레코드 마다 insex range scan을 체크할 때
- scanned N databases
: 쿼리를 통해 INFORMATION_SCHEMA DB에서 메타정보를 검색하는 경우
- Select tables optimized away
: MAX() 또는 MIN()만 SELECT 절에 사용되거나 GROUP BY에 사용되는 경우
쿼리가 적절한 인덱스를 사용할 수 없을 때 인덱스를 오름차순 혹은 내림차순으로 1건만 읽는 형태의 최적화가
적용되는 경우
- unqique row not found
: 두 개의 테이블이 각각 유니크 컬럼으로 OUTER 조인을 수행하는 쿼리에서 OUTER 테이블에 일치하는
레코드가 존재하지 않을 때
- Using filesort
: ORDER BY를 처리하기 위해 적절한 인덱스를 사용하지 못하는 경우
- Using index
: 데이터 파일을 전혀 읽지 않고 인덱스만 읽어서 쿼리를 모두 처리할 수 있는 경우
- Using index for group-by
: GROUP BY 처리가 인덱스를 이용하는 경우
- Using join buffer
: 읽은 레코드를 조인 버퍼에 저장하는 경우
- Ussing intersect
: 각각의 인덱스를 사용할 수 있는 조건이 AND로 연결된 경우 각 처리결과에서 교집합 추출
- Using union
: 각 인덱스를 사용할 수 있는 조건이 OR로 연결된 경우 각 처리 결과에서 합집합 추출
- Using sort_union
: 대량의 range들이 OR로 연결되어 있는 경우 WHERE 조건에 사용된 비교 조건이 모두 동등 조건이 아닐 때
- Using temporaty
: 쿼리를 처리하는 동안 중간 결과를 담아두기 위해 임시 테이블을 사용하는 경우
- Using where
: 스토리지 엔진에서 전달받은 데이터를 MySQL 엔진레이어에서 체크 조건으로 필터링 하는 경우
: 가장 흔하게 표시되는 키워드
Refference
'Database > MySQL' 카테고리의 다른 글
MySQL을 사용하면서 하지 말아야 할 17가지 (0) | 2023.05.15 |
---|---|
MySQL 테이블 수정 간단정리 (0) | 2023.01.30 |
MySQL 인덱스 생성 수정 / 삭제 (0) | 2022.10.30 |
MySQL 테이블 복사 (0) | 2022.10.30 |
MySQL 테이블 단편화 해결 방법 (0) | 2022.10.30 |