실행 계획에서 해당 테이블들의 id 칼럼이 같은지(조인이므로), 그러면서 Extra 칼럼에 아무것도 출력되지 않는지 확인하는 것이 가장 간단한 방법이다.
더 정확하게 확인하려면 EXPLAIN 명령을 실행한 직후, SHOW WARNINGS
명령으로 옵티마이저가 재작성(Re-Write)한 쿼리를 살펴보면 된다.
SHOW WARNINGS \G
IN(subquery)
형태의 세미 조인을 EXISTS(subquery)
형태로 튜닝한 것과 비슷한 방법으로 실행된다.optimizer_switch
시스템 변수에서 semijoin
옵션과 firstmatch
옵션이 모두 ON으로 활성화된 경우에만 사용할 수 있다.firstmatch
옵션만 OFF로 비활성화하면 된다.SELECT ... FROM ... WHERE expr IN (SELECT keypart1 FROM tab WHERE ...)
SELECT ... FROM ... WHERE expr IN (SELECT keypart2 FROM tab WHERE keypart1='상수' ...)
optimizer_switch
시스템 변수에서 loosescan 최적화 옵션을 OFF로 설정하면 된다.SET optimizer_switch='loosescan=off';
select_type
이 “Materialized”라고 표시된 임시 테이블이 하나 생기는 걸 볼 수 있다.-- 예를 들어, 이런 쿼리
SELECT *
FROM employees e
WHERE e.emp_no IN (
SELECT de.emp_no
FROM dept_emp de
WHERE de.from_date='1995-01-01'
GROUP BY de.dept_no
);
IN(subquery)
에서 서브쿼리는 상관 서브쿼리(Correlated subquery)가 아니어야 한다.optimizer_switch
시스템 변수에서 semijoin
옵션과 materialization
옵션이 모두 ON으로 활성화된 경우에만 사용할 수 있다.materialization
옵션만 OFF로 비활성화하면 된다.materialization
옵션이 비활성화된다면 세미 조인이 아닌 서브쿼리 최적화에서도 구체화를 이용한 최적화는 사용도지 못한다.-- 이런 쿼리를
SELECT * FROM employees e
WHERE e.emp_no IN (SELECT s.emp_no FROM salaries s WHERE s.salary > 150000);
-- 이렇게 수정
SELECT e.* FROM employees e, salaries s
WHERE e.emp_no = s.emp_no AND s.salary > 150000
GROUP BY e.emp_no;