본문 바로가기

SQL/MySql

실행계획

key_len

- 쿼리를 처리하기 위해 다중 컬럼으로 구성된 인덱스에서 몇개의 칼럼까지 사용했는지 알려줌,

 -  인덱스의 각 레코드에서 몇 바이트 까지 사용했는지 알려줌

 - dep_no 칼럼의 타입이 char(4) 이기 때문에 프라이머리 키에서 앞쪽 12바이트만 유요하게 사용

 - dep_no 칼럼은 utf-8문자 집합 사용 실제 utf8 문자는 1~3까지 가변적이긴 하지만 공간을 할당할때는 문자에 관계없이 고정적으로

   3바이트로 계산

 

ref

 - 접근 방법이 ref 방식으면 참조 조건(equal 비교조건) 으로 어떤 값이 제공되어/ㅆ는지 보여줌

 - 만약 상수값을 지정했다면 ref 칼ㄹ머의 값은 constfh 표시되고 다른 테이블의 칼럼값이면 그 테이블 명과 컬럼 명이 표시 됨

 - 가끔  func라고 표시될 때가 있는데 콜레이션 변환이나 값 자체의 연산을 거쳐서 참조되었다는 것을 의미

 

row1

 - 실행 계획의 효율성 판단을 위해 예측했던 레코드 건수를 보여줌.

 - 이 값은 각 스토리지 엔진별로 가지고 있는 통계 정보를 참조해 mysql 옵티마이저가 산출해 낸 예상 값이라 정확하지는 않음

 - 쿼리를 처리하기 위해 얼마나 많은 레코드를 디스크로 부터 읽고 체크해야 하는지 의미

 

extra

 

  const row now found (mysql 51부터)

  - const 접근 방식으로 테이블을 읽었지만 실제로 해당 테이블에 레코드가 1건도 존재하지 않으면 Extra 컬럼에 내용이 표시

 

  distint

   - 두 테이블에서 모두 조냊하는 칼럼만 중복없이 유니크하게 가져오기 위한 쿼리

 

Full scan on Null

  - col1 IN (SELECT col2 FROM ...)과 조건이 포함된 쿼리에서 자주 발생

  - 만약 col1의 값이 NULL이 된다면 결과적으과적으로 null in (select col2 from ...)과 같이 바뀐다.

 - 쿼리를 실행하는 중 col1이 NULL을 만나면 예비책으로 풀  테이블 스캔을 사용할 것이라는 사실을 알려준다.

 - 만약 col1 in (select col2 from...) 조건에서 col1이 not null로 정의되면 이러한 예비책을 사용하지 않는다.

 - null 규칙을ㅇ 무시해도 된다면 col1 is not null을 사용하면 규칙을 무시함.

 

Impoosible Having (mysql 5.1)

 - 쿼리에 사용된 having 절의 조건을 만족하는 레코드가 없을 때 실행 계획의 Extra 칼럼에 표시됨.

 - Impossible HAVING 출력되면 쿼리를 다시 점검 하자.

 

Impposible WHERE

 - WHERE가 조건이 항상 FALSE가 될 수 밖에 없는 경우

 

Impossible WHERE noticed after reading const tables

 -  실제로 실행되지 않으면 emp_no = 0 인 레코드가 있는지 판단할 수 없지만 옵티마이저는 0인 사원이 없다는것 까지 확인 함.

 

No matching min/ max row (Mysql 5.1 부타)

 - MIN이나 MAX 와 같은 집합 합수가 있는 쿼리의 조건절에 일치하는 레코드가 한건도 없을때 표시

 - 그리고 MIN 이나 MAX의 결과로 NULL이 반환됨

 

no matching row in const table (Mysql 5.1)

 - const 방식으로 접근할 때 일치하는 레코드가 없으면 표시 됨

 

no tables used (mysql 5.0의 "No table"에서 변경됨)

 - from절이 없는 쿼리 문장이나 from dual 형태의 실행 계획에서 노출 됨

 

 Not exists

 - 아우터 조인을 이용해 안티-조인을 수행하는 쿼리에서 extra 칼럼에 not exits가 표시됨

 - not exits 메시지는 이 쿼리를 not exits 형태의 쿼리로 변환해서 처리했음을 알 수 있다.

 

Range checked for each record(index map:n)

 - 매 레코드마다 인덱스 레인지 스캔을 체크한다.

 

 

Select tables optimized away

 - Min() 또는 MAX만 SELECT 절에 사용되거나 또는 GROUP BY로 MIN() MAX()를 조회하는 쿼리가 적절한 인덱스를 사용할 수 없을때 인덱스를 오름차순 또는 내림차순으로 1건만 읽는 형태의 최적화가 적용된다면 표시됨

 

unique ros not found(Mysql 5.1부터)

 - 두 개의 테이블이 각각 유니크(프라이머리 키 포함) 칼럼으로 아우터 조인을 수행하는 쿼리에서 아우터 테이블에 일치하는 레코드가 존재하지 안았을때 표시

 

 Using filesort

 - ORDER BY 처리가 인덱스를 사용하지 못할 때만 표시

 - 조회된 레코드를 정렬용 메모리 버퍼에 복사해 퀵 소트 알고리즘을 수행한다.

 - MYSQL옵티마이저는 레코드를 읽어서 소트 버퍼에 복사하고 정렬해서 그 결과를 클라이언트에 보냄

 - EXTRA 컬럼에 USING SORT가 출력되는 쿼리는 많은 부하를 줄 수 있기 때문에 가능하면 튜닝 또는 인덱스 생성이 좋다.

 

 

Using index(커버링 인덱스)

 

 - 데이터 파일을 전혀 읽지 않고 인덱스만 읽어서 쿼리를 모두 처리할 수 있을 때 extra 컬럼에 using index가 표시 됨

 

using idnex for group-by

 - group by 처리가 인덱스를 이용하면 정렬된 인덱스 칼럼을 순서대로 읽으면서 그룹핑 작업만 수행한다

 - gorup by 처리에 인덱스를 이용하면 레코드의 정렬이 필요하지 않고 인덱스의 필요한 부분만 읽으면 되기 때문에 상당히 효육적이고 빠르다.

 - goup by 처리를 위해 인덱스를 통한 데이터 읽는 방법을 루스 인덱스 스캔이라 한다.

 

   타이트 인덱스 스캔을 통한 group by 처리

     - 인덱스를 이용해 group by 절을 처리할 수 있더라도 avg()나 sum() 또는 count(*)와 같이 조회하려는 값이 모든 인덱스를 다 읽어야 할때는 루스   

       인덱스를 사용 할 수 없음.

    

   루스 인덱스 스캔을 통한 group by 처리

     - 단일 컬럼 구성된 인덱스에서는 그룹핑 칼럼 말고는 아무것도 조회하지 않는 쿼리에서 루스 인덱스 스캔을 사용할 수 있다.

     - 다중 컬럼으로 만들어진 인덱스 에서는 group by 절이 인덱스를 사용할 수 있어야 하고 min() max()와 같이 조회하는 값이 인덱스에

       첫 번째 또는 마지막만 읽어되 되는 쿼리는 루스 인덱스 스캔이 사용될 수 있다.

 

where조건에의해서 사용 여부가 영향을 받는다

  where 조건절이 없는경우

  - where 조건이  전혀 없는 쿼리는 group by와 조회하는 컬럼이 루스인덱스 스캔을 사용할 수 있는 조건만 갖추면 된다.

 

  where 조건절만 있지만 검색을 위해 인덱스를 사용하지 못하는경우

    - group by 절은 인덱스를 사용하지만 where 조건절이 인겍스를 사용하지 못할 때는 group by를 위해 인덱스를 읽은 후 where 조건의 비료를 위해 데이터를 읽어야 한다.

   - 이 경우도 루스 인덱스 스캔을 이용 못함.

 

  where절의 조건이 이으며 검색을 위해 인덱스를 사용하는 경우

  - where조건이 검색하는데 사용한 인덱스를 group by 처리가 다시 사용할 수 있을때만 루스 인덱스 스캔을 이용할 수 있다

  - 만약 서로 다르다면 where 조건절이 인덱스를 사용하도록 실행 계획을 세우는 경향이 있다.

  - where와 group by가 같은 인덱스를 사용하더라도 루스 인덱스 스캔을 이용하지 않을 수 도 있다 왜냐하면 레코드 건수 가 적으면 루스 인덱스 스캔을 사용하지 않아도 매우 빠르게 처리 될 수 있다.

 

using join buffer(Mysql 5.1부터)

 - 드리븐 테이블의 비효율적 검색을 보완하기 위해 mysql 서버는 드라이빙 테이블에서 읽은 레코드를 임시 공간에 보관해두고 필요할때 재사용하게 해준다

 - 레코드를 임시로 보관해두는 임시공간을 조인 버퍼라 하며 extra 컬럼에 usin join buffer라 표시됨

 - 조인 버퍼는 join_buffer_size라는 시스템 설정 변수에 최대 사용 가능한 버퍼 크기를 설정할 수 있음.

 

using temporary

 - 쿼리를 처리하는 동안 중간 결과를 담아 두기 위해임시테이블을 사용한다.

 - 임시 테이블은 메모리상에 생성될 수 도 있고 디스크상 생성될 수도 있다.

 - from절에 사용한 서브쿼리는 무조건 임시 테이블을 생성한ㄷㅏ.

 - count(distinct column1)를 포함하는 쿼리도 인덱스를 사용할 수 없는 경우 임시테이블이 만들어진다.

 - union 이나 union all이 사용되는 쿼리도 항상 임시테이블을 만든다.

  인덱스를 사용하지 못하는 정렬 또한 임시 버퍼 공간을 사용하는데 정렬해야할 레코드가 많아지면 디스크를 사용한다.

 

using where 

 - mysql은 크게 msqy엔진과 스토리지 엔진으로 나뉜다.

 - 스토리지 엔진은 디스크나 메모리상에서 필요한 레코드를 읽거나 저장하며 msyql엔진은 스토리지 엔진에서 받은 레코드를 가공 또는 연산 하는 작업을 수행

 - msyql레이어에서 별도 가공해서 필터링 작업을 처리한 경우만 using where가 표시

 

 

 

 

 

루스 인덱스 스캔

 - 인덱스 스킵 스캔

 - 레인지 스캔과 비슷하게 동작하지만 중간마다 필요치 않은 인덱스 키값을 무시하고 다음으로 넘어가는 형태로 처리

 - 일반적으로 group by 또는 집합 함수 가운데 MAX() 또는 MIN() 함수에 대해 최적화를 하는 경우에 사용

 

타이트 인덱스 스캔

 - 인덱스 풀 스캔, 인덱스 레인지 스캔을 말함.

 

 

 

 

 

 

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

Mysql Lock  (0) 2017.11.20
1부 3장. SQL 소개  (0) 2017.11.15
쿼리 실행 절차 및 옵티마이저 종류  (0) 2017.11.15
실행계획 ID 컬럼과 select_type  (0) 2017.11.15
mysql 정렬  (0) 2017.11.15