SELECT *
FROM employees e
INNER JOIN salaries s ON s.emp_no=e.emp_no
WHERE e.first_name='Matt'
AND e.hire_Date BETWEEN '1995-11-21' AND 1986-11-21';
id | table | type | key | rows | filtered | Extra |
---|---|---|---|---|---|---|
1 | e | ref | ix_firstname | 233 | 100.00 | Using where |
1 | s | ref | PRIMARY | 10 | 100.00 | NULL |
employees
테이블에서 ix_firstname
인덱스로 조건에 맞는 233건 레코드를 검색hire_date
조건에 맞는 레코드를 필터링하는데 이 실행 계획에서는 filered 칼럼이 100인 것으로 보아 233건 모두 만족할 것으로 예측했다.salaries
테이블의 프라이머리 키를 이용해 slalaries
테이블의 레코드를 읽는데 옵티마이저는 employees
테이블 레코드 한 건당 salaries
테이블 레코드 10건이 일치할 것으로 예상했다.id | table | type | key | rows | filtered | Extra |
---|---|---|---|---|---|---|
1 | e | ref | ix_firstname | 233 | 23.20 | Using where |
1 | s | ref | PRIMARY | 10 | 100.00 | NULL |
first_name
으로 거른 결과인 233건에서 hire_date
조건까지 만족하는 값은 233건에서 23%라고 예측한 것condition_fanout_filter
를 활성화하면 인덱스를 사용할 수 없는 조건에 대해서도 얼마나 조건을 충족할지를 고려하게 된다.
FROM
절에 서브 쿼리가 있으면 먼저 실행해서 임시 테이블로 만든 다음 외부 쿼리를 처리했다.SELECT * FROM (
SELECT * FROM employees WHERE first_name='Matt'
) derived_table
WHERE derived_table.hire_date='1996-04-03';
id | select_type | table | type | key |
---|---|---|---|---|
1 | PRIMARY | ref | ||
2 | DERIVED | employees | ref | ix_firstname |
employees
테이블을 읽는 select_type
이 DERIVED
인 것을 보아 조건에 맞는 임시 테이블을 생성했다고 볼 수 있다.
derived_merge
옵션을 활성화하면 실행 계획이 아래와 같이 변한다.id | select_type | table | type | key |
---|---|---|---|---|
1 | SIMPLE | employees | index_merge | ix_hiredate, ix_firstname |
DISTINCT
가 사용된 서브 쿼리GROUP BY
나 HAVING
이 사용된 서브 쿼리LIMIT
가 사용된 서브 쿼리UNION
또는 UNION ALL
을 포함하는 서브 쿼리SELECT
절에 사용된 서브 쿼리