본문 바로가기

db/MySql

DB 실행 계획 분석 EXPLAIN - 2

Intro

 실행 계획 분석 1에 이어서 다른 컬럼을 살펴보자.

 

5. key 칼럼

실행계획에서 사용할 인덱스 정보를 나타내는 컬럼이다. 인덱스를 사용하지 못하는 경우에는 NULL이 표시된다.

사용할 인덱스 정보를 통해서 실행 쿼리가 어떤 인덱스를 사용해 최적화를 이루는지 알 수 있게 한다.

 

6. ken_len 칼럼

key로 사용할 인덱스가 단일로 사용될 수도 있지만 복합적으로 여러개의 인덱스를 사용할 수 있다. key_len을 통해서 인덱스의 각 레코드에서 몇 바이트까지 사용했는지를 알 수 있다.

 

7. ref 칼럼

접근 방식(type)이 ref 방식이면 참조조건으로 어떤 값을 이용하는지를 보여주는 칼럼이다. 

+) 만약 이 값이 func 으로 표시된다면 조인 칼럼 타입이 일치하지 않아서 추가적인 가공처리(타입 일치 작업)이 필요한 경우이다. 성능을 위해서는 가급적 조인 칼럼 타입을 일치하는 것이 좋다.

 

8. rows 칼럼

해당 실행 계획이 얼마나 많은 레코드를 수를 처리하는지를 예측한 예상치를 나타낸다.

해당 값은 예상치이기 때문에 정확하지는 않다. 그래서 LIMIT를 적용한 경우에도 터무니없는 예상치를 나타내기도 한다.

rows 칼럼을 통해서 해당 계획이 얼마나 효율적인지 비효율적인지 수치로 짐작할 수 있는 지표로 사용하기 좋다.

 

9. Extra 칼럼

성능과 관련된 중요한 내용이 자주 표시되는 칼럼이다. 추가적인 정보를 문장의 형태로 보여준다.

  • const row not found
    • const 접근 방식으로 테이블을 읽었지만 실제로 해당 테이블에 레코드가 1건도 존재하지 않으면 Extra 칼럼에 이 내용이 표시된다.
  • Distinct
SELECT DISTINCT d.dest_no FROM department d, dest_emp de WHERE de.dept_no = d.dept_no;

다음 쿼리와 같이 DISTINCT를 이용한 중복 방지 처리를 하는 경우에 나타나는 정보이다. 

조인을 하는 과정에서 다음 쿼리를 dest_no이 일치하는 컬럼을 찾는다. 하지만 필요한 칼럼이 dest_no 하나이고 중복이 필요없다. 따라서 조인시 불필요한 컬럼은 무시한다. 이 과정을 나타내는 것은 DISTINCT이다.

DISTINCT 처리하면 빨간 선으로 표시된 포인트들은 구지 탐색하지 않아도 문제없다.

  • Full scan on NULL key
    • col IN (select ...) 와 같이 서브 쿼리를 통한 IN 연산에서 col의 값이 NULL일 가능성이 있을 때 나타나는 정보이다.
    • NULL in (서브 쿼리) 연산은 다음 규칙을 통해서 계산된다.
      • 서브 쿼리가 1건이라도 결과 레코드가 있다면 최종 비교 결과는 NULL
      • 서브 쿼리가 1건도 결과 레코드가 없다면 최종 비교 결과는 FALSE
    • NULL in (서브 쿼리)를 알기 위해서는 풀 테이블 스캔을 통해서 알 수 있기에 이를 경고하는 것이다.
  • Impossible HAVING
    • HAVING 절의 조건을 만족하는 레코드가 없다는 것을 나타내는 정보
    • 해당 메시지가 출력된 경우 쿼리 이상이 있는 경우가 있기에 쿼리의 내용을 다시 점검하는 것이 좋음
  • Impossible WHERE
    • WHERE 절의 조건이 항상 FALSE가 될 수밖에 없는 경우 나타내는 정보
  • Impossible WHERE noticed after reading const tables
    • "const 테이블을 읽은 이후에 보기 where 조건이 불가능해" 라고 알려주는 정보
  • No matching min/max row
    • MIN(), MAX()와 같은 집합 함수가 있는 쿼리의 조건절에 일치하는 레코드가 한 건도 없을 때 나타나는 정보
    • 데이터가 있어야 최대, 최소 값을 구하지....ㅠㅠ > 이런 느낌
  • no matching row in const table
    • Impossible where 과 같은 종류의 정보
    • 조인에 사용된 테이블에서 const 방식으로 접근할 때, 일치하는 레코드가 없다는 경우
  • no tables used
    • FROM 절 자체가 없거나, FROM 절에 상수 테이블을 의미하는 DUAL이 사용되는 경우
  • Not exists
    • 아우터 조인을 이용해서 안티 조인을 수행한 쿼리에서 나타내는 메시지
    • NOT IN, NOT EXISTS 연산보다는 아우터 조인(col = null)을 이용하는 것이 빠른 성능을 낸다.
  • Range checked for each record
    • 조인시에 드라이빙 테이블의 레코드마다 인덱스 레인지 스캔을 체크한다는 것.
  • Select tables optimized away
    • MIN(), MAX() 만 select 절에 사용되거나 GROUP BY로 MIN, MAX 를 조회하는 쿼리가 적절한 인덱스를 사용할 수 있을 때, 인덱스를 오름차순 또는 내림차순으로 1건만 읽는 형태의 최적화를 적용했다는 뜻
  • unique row not found
    • 아우터 조인을 수행하는 쿼리에서 아우터 테이블에 일치하는 레코드가 존재하지 않는 경우
  • Using filesort
    • 조회된 레코드를 정렬 용 메모리 버퍼에 복사해 퀵소트 알고리즘을 수행한다는 뜻
    • 적절한 인덱스를 이용하여 정렬 처리(order by )를 하지 못한 경우를 뜻함.
    • 부하가 큰 작업이기 때문에 쿼리를 튜닝하거나 인덱스를 생성하는 등 방안을 고려하는 것이 필요.
  • Using index
    • 데이터 파일을 전혀 읽지 않고 인덱스만 읽어서 쿼리를 모두 처리할 수 있는 경우
    • 인덱스만을 이용하기 때문에 성능상 이점이 있는 경우
    • 인덱스만으로 처리되는 것을 커버링 인덱스(Covering index)라고 한다.
  • Using index for group-by
    • 루스 인덱스 스캔을 사용한 경우
    • GROUP BY 처리가 인덱스를 이용하면 정렬된 인덱스 칼럼을 순서대로 읽으면서 그룹핑 작업만 수행하면 되기 때문에 상당히 효율적이고 빠르게 처리된다.
    • GROUP BY, DISTINCT 연산에서 사용할 수 있는 최적의 튜닝 방법 = 루스 인덱스 스캔
  • Using join buffer
    • Driven 테이블의 비효율적인 검색을 보완하기 위해서 Driving 테이블에서 읽은 레코드를 임시 공간(조인버퍼)에 캐시해두는 것 => 즉 조인 버퍼를 사용한 경우라는 것
  • Using where
    • 스토리지 엔진이 아닌 MySQL 엔진 레이어에서 별도의 가공을 해서 필터링 작업을 처리한 경우

 

출처 : Real MySQL 이성욱 지음

'db > MySql' 카테고리의 다른 글

SELECT 최적화  (0) 2023.03.17
MySQL 연산자와 내장 함수  (0) 2023.03.11
MySQL의 주요 처리 방식  (0) 2023.03.06
DB 실행 계획 분석 EXPLAIN - 1  (0) 2023.02.22