'실행 계획'에 해당되는 글 2건

  1. 2015.05.15 [Mysql] 실행계획2 (1)
  2. 2015.05.11 [Mysql] 실행계획
MySQL2015.05.15 00:31

 

3. 테이블 컬럼

MySQL의 실행 계획은 단위 SELECT 쿼리 기준이 아니라 테이블 기준으로 표시된다.

테이블 컬럼에 "<>"로 둘러싸인 이름이 명시되는 경우 해당 테이블은 임시 테이블을 의미한다.

   

EXPLAIN

SELECT *

FROM

(SELECT de.emp_no FROM dept_emp de) tb,

employees e

WHERE e.emp_no = tb.emp_no;

   

   

4. type 컬럼

각 테이블 접근 방식으로 해석하면 된다.

   

system

레코드가 1건만 존재하는 테이블 또는 한 건도 존재하지 않는 테이블을 참조하는 형태의 접근 방법(MyISAM, MEMORY 테이블에만 해당)

   

const

쿼리가 프라이머리 키나 유니크 키 칼럼을 이용하는 WHERE 조건 절을 가지고 있으며, 반드시 1건을 반환하는 쿼리 방식

   

EXPLAIN

SELECT * FROM employees WHERE emp_no = 10001;

   

   

eq_ref

조인에서 처음 읽은 테이블의 칼럼 값을 그 다음에 읽어야 할 테이블의 프라이머리 키나 유니크 키 칼럼의 검색 조건에 사용할 때를 eq_ref라고 한다.

   

EXPLAIN

SELECT * FROM dept_emp de, employees e

WHERE e.emp_no =de.emp_no AND de.dept_no = 'd005';

   

   

ref

인덱스의 종류와 관계없이 동등 조건으로 검색할 때는 ref 접근 방법이 사용된다.

   

EXPLAIN

SELECT * FROM dept_emp WHERE dept_no='d005';

   

   

ref_or_null

ref 접근 방식과 같은데, NULL 비교가 추가된 형태다.

   

uinique_subquery

WHERE 조건 절에서 사용될 수 있는 IN (서브쿼리) 형태의 쿼리를 위한 접근 방식으로 중복되지 않은 유니크한 값만 반환할 때 이 접근 방법을 사용 한다.

   

EXPLAIN

SELECT * FROM departments WHERE dept_no IN (SELECT dept_no FROM dept_emp WHERE emp_no=10001);

   

   

index_subquery

IN(서브쿼리)에서 서브쿼리가 중복된 값을 반환할 수는 있지만 중복된 값을 인덱스를 이용해 제거할 수 있을 때 index_subquery 접근 방식이 사용된다.

   

EXPLAIN

SELECT * FROM departments WHERE dept_no IN (

SELECT dept_no FROM dept_emp WHERE dept_no BETWEEN 'd001' AND 'd003');

   

-> 버전이 달라서 실행 계획이 표현이 조금 다름.

   

range

인덱스 레인지 스캔 형태의 접근 방법

   

EXPLAIN

SELECT dept_no FROM dept_emp WHERE dept_no BETWEEN 'd001' AND 'd003';

   

   

index_merge

2개의 이상의 인덱스를 이용해 각각의 검색 결과를 만들어 낸 후 그 결과를 병합하는 처리 방식

   

EXPLAIN

SELECT * FROM employees

WHERE emp_no BETWEEN 10001 AND 11000

OR first_name='Smith';

   

   

index

접근 방식은 인덱스를 처음부터 끝까지 읽는 인덱스 풀 스캔을 의미한다.

   

EXPLAIN

SELECT * FROM departments ORDER BY dept_name DESC LIMIT 10;

   

   

ALL

풀 테이블 스캔을 의미하는 접근 방식

   

5. key_len

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

   

EXPLAIN

SELECT * FROM dept_emp WHERE dept_no='d005';

   

   

   

   

char

3바이트

integer

4바이트

date

3바이트

   

6. ref

참조 조건으로 어떤 값이 제공됐는지 보여 준다.

const: 상수값

테이블명.칼럼명: 칼럼값

EXPLAIN

SELECT *

FROM employees e, dept_emp de

WHERE e.emp_no = de.emp_no;

   

   

func: 콜레이션 변환, 연산을 거친 값

EXPLAIN

SELECT *

FROM employees e, dept_emp de

WHERE e.emp_no =(de.emp_no-1);

   

   

7. rows

실행 계획의 효율성 판단을 위해 예측했던 레코드 건수를 보여 준다. 예상 값이라 정확하지 않다

   

EXPLAIN

SELECT * FROM dept_emp WHERE from_date >= '1985-01-01';

   

   

EXPLAIN

SELECT * FROM dept_emp WHERE from_date >= '2002-07-01';

   

   

EXPLAIN

SELECT * FROM dept_emp WHERE from_date >= '1985-01-01' LIMIT 10;

   

;

   

>

신고

'MySQL' 카테고리의 다른 글

[Mysql] 변수  (0) 2016.05.19
[Mysql] 제어문  (0) 2016.05.19
[Mysql] 스토어드 함수  (0) 2016.05.17
[Mysql] 스토어드 프로시저  (0) 2016.05.17
[Mysql] 실행계획2  (1) 2015.05.15
[Mysql] 실행계획  (0) 2015.05.11
Posted by TM ~ing
MySQL2015.05.11 19:30

 

1. id 컬럼

- 단위 SELECT 쿼리별 부여되는 식별자 값이다.

- 두개의 테이블을 조인하는 쿼리에서는 같은 id가 부여된다.

EXPLAIN

SELECT e.emp_no, e.first_name, s.from_date, s.salary

FROM employees e, salaries s

WHERE e.emp_no = s.emp_no

LIMIT 10;

   

   

- 쿼리 문장이 3개의 SELECT로 구성돼 있으면 실행 계획의 각 레코드는 각기 다른 id를 부여받는다.

EXPLAIN

SELECT

((SELECT COUNT(*) FROM employees) + (SELECT COUNT(*) FROM departments) ) AS total_count;

   

   

2. select_type 컬럼

어떤 타입의 쿼리인지 표시되는 칼럼

   

SIMPLE

UNION이나 서브 쿼리를 사용하지 않는 단순한 SELECT의 경우

   

PRIMARY

UNION이나 서브 쿼리가 포함된 SELECT 쿼리의 실행 계획에서 가장 바깥쪽에 있는 단위 쿼리

   

UNION

UNION으로 결합하는 단위 SELECT 쿼리 가운데 첫 번째를 제외한 두 번째 이후 단위 SELECT의 select_type

EXPLAIN

SELECT * FROM (

(SELECT emp_no FROM employees e1 LIMIT 10)

UNION ALL

(SELECT emp_no FROM employees e2 LIMIT 10)

UNION ALL

(SELECT emp_no FROM employees e3 LIMIT 10)

) tb;

   

   

DEPENDENT UNION

DEPENDENT UNION은 UNION이나 UNION ALL로 결합된 단위 쿼리가 외부의 영향에 의해 영향을 받는 것을 의미함

*select type에 DEPENDENT가 나오는 쿼리는 비효율적인 경우가 많음

EXPLAIN

SELECT

e.first_name,

(SELECT CONCAT('Salary Change count : ', COUNT(*)) AS message

FROM salaries s WHERE s.emp_no = e.emp_no

UNION

SELECT CONCAT('Department Change count : ' , COUNT(*)) AS message

FROM dept_emp de WHERE de.emp_no = e.emp_no

) AS message

FROM employees e

WHERE e.emp_no=10001;

   

   

UNION RESULT

UNION 결과를 담아두는 테이블을 의미함

EXPLAIN

SELECT emp_no FROM salaries WHERE salary > 100000

UNION ALL

SELECT emp_no FROM dept_emp WHERE from_date > '2001-01-01';

   

   

SUBQUERY

FROM 절 이외에서 사용되는 서브 쿼리

EXPLAIN

SELECT e.first_name,

(SELECT COUNT(*) FROM dept_emp de, dept_manager dm WHERE dm.dept_no=de.dept_no) AS cnt

FROM employees e

WHERE e.emp_no = 10001;

   

   

DEPENDENT SUBQUERY

서브 쿼리가 바깥쪽(Outer) SELECT 쿼리에서 정의된 컬럼을 사용하는 경우

EXPLAIN

SELECT e.first_name,

(SELECT COUNT(*)

FROM dept_emp de, dept_manager dm

WHERE dm.dept_no = de.dept_no AND de.emp_no = e.emp_no) as cnt

FROM employees e

WHERE e.emp_no = 10001;

   

   

DERIVED

서브 쿼리가 FROM 절에 사용된 경우 항상 DERIVED인 실행 계획을 만든다.

MySQL은 FROM 절에 사용된 서브 쿼리를 제대로 최적화하지 못할 때가 대부분이다.

EXPLAIN

SELECT *

FROM (SELECT de.emp_no FROM dept_emp de) tb,

employees e

WHERE e.emp_no=tb.emp_no;

   

--변경후

EXPLAIN

SELECT *

FROM dept_emp de, employees e

where de.emp_no=e.emp_no;

   

   

UNCACHEABLE SUBQUERY

조건이 똑같은 서브 쿼리가 실행될 때는 다시 실행하지 않고 이전의 실행 결과를 그대로 사용할 수 있게 서브 쿼리의 결과를 내부적인 캐시 공간에 담아둔다. 하지만 아래의 요소로 인하여, 해당 캐시를 사용하지 못할 수 있는데 이런 서브 쿼리는 UNCACHEABLE SUBQUERY라 한다.

   

- 사용자 변수가 서브 쿼리에 사용된 경우

- NOT-DETERMINISTIC 속성의 스토어드 루틴이 서브 쿼리 내에 사용된 경우

- UUID()나 RAND()와 같이 결과값이 호출활 때마다 달라지는 함수가 서브 쿼리에 사용된 경우

   

EXPLAIN

SELECT *

FROM employees e

WHERE e.emp_no = ( SELECT @status FROM dept_emp de WHERE de.dept_no ='d005');

   

   

UNCACHEABLE UNION

위의 UNCACHEABLE SUBQUERY가 UNION일 경우 발생하는 실행 계획이다.

신고

'MySQL' 카테고리의 다른 글

[Mysql] 변수  (0) 2016.05.19
[Mysql] 제어문  (0) 2016.05.19
[Mysql] 스토어드 함수  (0) 2016.05.17
[Mysql] 스토어드 프로시저  (0) 2016.05.17
[Mysql] 실행계획2  (1) 2015.05.15
[Mysql] 실행계획  (0) 2015.05.11
Posted by TM ~ing

티스토리 툴바