Mysql 실행계획 정리
MySQL Explain 결과는 일반적으로 쿼리 실행 시간, 반환된 행의 수, 사용된 인덱스 등을 포함합니다.
실행계획 결과 항목 설명
EXPLAIN SELECT * FROM member WHERE id=1;
- id: 쿼리의 실행 순서를 나타내는 값입니다.
- select_type: 쿼리의 유형을 나타내는 값입니다. (e.g. SIMPLE, PRIMARY, SUBQUERY 등)
- table: 쿼리에서 사용된 테이블의 이름입니다.
- partitions: 쿼리에서 사용된 파티션의 이름입니다.
- type: 테이블에 접근하는 방법을 나타내는 값입니다. (e.g. ALL, index, range 등)
- possible_keys: 사용 가능한 인덱스의 이름입니다.
- key: 쿼리에서 실제로 사용된 인덱스의 이름입니다.
- key_len: 쿼리에서 사용된 인덱스의 길이입니다.
- ref: 인덱스를 사용한 조인 조건입니다.
- rows: 쿼리에서 반환되는 행의 수입니다.
- filtered: 쿼리에서 반환된 행 중 조건에 부합하는 행의 비율입니다.
- Extra: 추가 정보입니다.
select_type
쿼리 유형을 나타냅니다. 쿼리가 처리되는지 이해하는데 도움이 됩니다. 쿼리의 처리 방식과 테이블 간의 연결 등에 따라 달라지기 때문에 유형에 맞는 최적화된 방법 선택이 중요합니다.
- SIMPLE: 단일 테이블에서 데이터를 조회. 단순한 데이터 조회인 경우 입니다.
- PRIMARY: 다른 쿼리의 서브쿼리로 사용되는 경우가 대부분 입니다. 서브쿼리, 외부쿼리 사용 시 첫 번쨰 쿼리인 경우 입니다.
- SUBQUERY: 다른 쿼리의 서브쿼리로 사용. 실행 계획이 먼저 실행된 다음 외부 쿼리에 의해 실행 됩니다.
- DERIVED: FROM 절에 대한 서브쿼리.
- UNION: UNION 을 사용하여 두 개 이상의 SELECT 문을 결합하는 경우 입니다.
- UNION RESULT: UNION 연산자로 결합된 결과를 반환하는 경우 입니다.
- DEPENDENT UNION: UNION 연산자가 서브쿼리에 의존하는 경우 입니다.
- DEPENDENT SUBQUERY: 서브쿼리가 [[외부 쿼리]]에 의존하는 경우 입니다.
type
테이블 접근 방식을 나타냅니다. 쿼리 성능을 이해하고 최적화하는 데 중요합니다. type 이 최적이 아닌 경우 인덱스 추가 및 쿼리 최적화가 필요합니다. 쿼리가 사용하는 인덱스도 영향을 미치므로 key, rows 를 잘 봐야 합니다.
- system: 하나의 레코드만 있는 경우에 해당하는 최적의 유형입니다.
- const: 기본 키나 유니크 인덱스를 이용하여 단일 레코드를 가져오는 경우입니다.
- eq_ref: 연결된 테이블에서 인덱스를 사용하여 단일 레코드를 가져오는 경우입니다.
- ref: 인덱스를 사용하여 특정 범위의 레코드를 가져오는 경우입니다.
- fulltext: FULLTEXT 인덱스를 사용하여 텍스트 검색을 수행하는 경우입니다.
- ref_or_null: NULL 값을 포함한 레코드를 검색하는 경우입니다.
- index_merge: 여러 개의 인덱스를 병합하여 검색하는 경우입니다.
- unique_subquery: 서브쿼리에서 유니크 인덱스를 사용하여 레코드를 가져오는 경우입니다.
- index_subquery: 서브쿼리에서 인덱스를 사용하여 레코드를 가져오는 경우입니다.
- range: 인덱스를 사용하여 일부 레코드를 가져오는 경우입니다.
- index: 인덱스를 스캔하여 모든 레코드를 가져오는 경우입니다.
- all: 테이블을 전체 스캔하여 모든 레코드를 가져오는 경우입니다.
- NULL: 어떤 유형에도 해당하지 않는 경우입니다.
말 그대로 쿼리 실행에 대한 추가 정보 입니다. 성능을 이해하고 최적화 하는데 도움이 되는 정보를 보여줍니다.
- Using where:
WHERE
절에서 추가적인 필터링을 수행합니다. WHERE
절에서 인덱스를 사용하지 않는 경우 입니다. 스토리지 엔진에서 조회된 후 Mysql 엔진에서 필터링 된 데이터가 존재하는 경우이다. 이 경우 rows
, filtered
를 잘 살펴 봐야 한다. 실제 필요한 데이터보다 많은 데이터를 읽은 뒤 필터링 되어 버려진다면 비효율적이라고 볼 수 있다. - Using temporary: 임시 테이블을 생성하여 쿼리를 실행 합니다.
ORDER BY
또는 GROUP BY
시 발생하는데 성능에 문제가 있는 경우에는 ORDER BY
또는 GROUP BY
컬럼에 인덱스를 추가하는 방법이 있습니다.- 서브쿼리 사용
- COUNT(DISTINCT c1) 같은 쿼리에서 인덱스를 사용 못하는 경우
- UNION, UNION ALL 사용
- 등등
- Using filesort:
ORDER BY
작업에서 파일 정렬을 수행하는 경우 입니다. ORDER BY
또는 GROUP BY
에서 많은 데이터를 정렬하는 경우 발생합니다. ORDER BY
또는 GROUP BY
컬럼에 인덱스를 추가하거나 LIMIT
를 추가하여 성능 향상을 해볼 수 있습니다. - Using index: 인덱스 만을 사용하여 쿼리 실행이 가능하다는 의미 입니다. 쿼리 성능이 좋다는 의미 입니다.
- Using join buffer (Block Nested Loop):
JOIN
을 하여 쿼리를 실행할 때에 JOIN BUFFER
가 사용된 경우 입니다. JOIN
되는 컬럼에 적절한 인덱스가 존재하여 크기가 적절한 경우에는 신경쓰지 않아도 됩니다. (일반 적인 웹 서비스 기준 1M 정도) - Using index condition: 스토리지 엔진 레벨에서 범위제한 조건외에 체크 조건도 같이 처리하는 경우 입니다.
Condition push down
은 스토리지 엔진, Mysql 엔진이 분리 됨에 따라 발생하는 비효율적인 처리를 개선한 방식으로 실행됨을 말합니다.
- Impossible where:
WHERE
절의 조건이 항상 거짓인 경우 입니다. - Select tables optimized away: 쿼리 최적화가 잘된 경우 입니다.
- No matching min/max row: 인덱스 범위 검색 시 최소 또는 최대 값이 일치하지 않는 경우 발생합니다.
댓글
댓글 쓰기