EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT de.emp_no FROM dept_emp de WHERE de.dept_no = 'd009')
;
+------+--------------------+-------+--------+---------+------------+--------+--------------------------+
| id | select_type | table | type | key | ref | rows | Extra |
+------+--------------------+-------+--------+---------+------------+--------+--------------------------+
| 1 | PRIMARY | e | ALL | NULL | NULL | 300252 | Using where |
| 2 | DEPENDENT SUBQUERY | de | eq_ref | PRIMARY | const,func | 1 | Using where; Using index |
+------+--------------------+-------+--------+---------+------------+--------+--------------------------+
-- 책 내용 옮겨 적은 거
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT de.emp_no FROM dept_emp de WHERE de.dept_no = 'd009')
;
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+--------------------------+
| 1 | PRIMARY | de | ref | PRIMARY,ix_empno_fromdate | PRIMARY | 12 | const | 46914 | Using where; Using index |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.emp_no | 1 | |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+--------------------------+
EXPLAIN EXTENDED
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT de.emp_no FROM dept_emp de WHERE de.dept_no = 'd009')
;
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+----------+--------------------------+
| 1 | PRIMARY | de | ref | PRIMARY,ix_empno_fromdate | PRIMARY | 12 | const | 46914 | 100.00 | Using where; Using index |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.emp_no | 1 | 100.00 | |
+------+-------------+-------+--------+---------------------------+---------+---------+---------------------+-------+----------+--------------------------+
2 rows in set, 1 warning (0.00 sec)
SHOW warnings;
+-------+------+-----------------------------------------------------------------+
| Level | Code | Message |
+-------+------+-----------------------------------------------------------------+
| Note | 1003 | select `employees`.`e`.`emp_no` AS `emp_no` |
| | | , `employees`.`e`.`birth_date` AS `birth_date` |
| | | , `employees`.`e`.`first_name` AS `first_name` |
| | | , `employees`.`e`.`last_name` AS `last_name` |
| | | , `employees`.`e`.`gender` AS `gender` |
| | | , `employees`.`e`.`hire_date` AS `hire_date` |
| | | from `employees`.`dept_emp` `de` |
| | | join `employees`.`employees` `e` |
| | | where ( (`employees`.`e`.`emp_no` = `employees`.`de`.`emp_no`) |
| | | and (`employees`.`de`.`dept_no` = 'd009') ) |
+-------+------+-----------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [employees]>
EXPLAIN
SELECT *
FROM employees e
WHERE e.first_name = 'Matt'
AND e.emp_no IN (SELECT t.emp_no
FROM titles t
WHERE t.from_date BETWEEN '1995-01-01' AND '1995-01-30'
)
;
+------+-------------+-------+------+----------------------+--------------+---------+--------------------+------+-----------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+----------------------+--------------+---------+--------------------+------+-----------------------------------------+
| 1 | PRIMARY | e | ref | PRIMARY,ix_firstname | ix_firstname | 44 | const | 233 | Using index condition |
| 1 | PRIMARY | t | ref | PRIMARY | PRIMARY | 4 | employees.e.emp_no | 1 | Using where; Using index; FirstMatch(e) |
+------+-------------+-------+------+----------------------+--------------+---------+--------------------+------+-----------------------------------------+
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT t.emp_no
FROM titles t
WHERE t.from_date BETWEEN '1995-01-01' AND '1995-01-30'
)
;
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+--------------------------+
| 1 | PRIMARY | e | ALL | PRIMARY | NULL | NULL | NULL | 299423 | |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 4 | func | 1 | |
| 2 | MATERIALIZED | t | index | PRIMARY | PRIMARY | 159 | NULL | 442189 | Using where; Using index |
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+--------------------------+
ALTER TABLE titles ADD INDEX ix_fromdate(from_date);
Query OK, 0 rows affected (48.29 sec)
Records: 0 Duplicates: 0 Warnings: 0
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT t.emp_no
FROM titles t
WHERE t.from_date BETWEEN '1995-01-01' AND '1995-01-30'
)
;
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
| 1 | PRIMARY | <subquery2> | ALL | distinct_key | NULL | NULL | NULL | 2689 | |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.t.emp_no | 1 | |
| 2 | MATERIALIZED | t | range | PRIMARY,ix_fromdate | ix_fromdate | 3 | NULL | 2689 | Using where; Using index |
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT t.emp_no
FROM titles t
WHERE t.from_date BETWEEN '1995-01-01' AND '1995-01-30'
GROUP BY t.title
)
;
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
| 1 | PRIMARY | <subquery2> | ALL | distinct_key | NULL | NULL | NULL | 2689 | |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.t.emp_no | 1 | |
| 2 | MATERIALIZED | t | range | PRIMARY,ix_fromdate | ix_fromdate | 3 | NULL | 2689 | Using where; Using index |
+------+--------------+-------------+--------+---------------------+-------------+---------+--------------------+------+--------------------------+
EXPLAIN
SELECT *
FROM departments d -- 9건
WHERE d.dept_no IN (SELECT de.dept_no
FROM dept_emp de -- 33만건
)
;
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+-------------+
| 1 | PRIMARY | d | index | PRIMARY | ux_deptname | 122 | NULL | 9 | Using index |
| 1 | PRIMARY | <subquery2> | eq_ref | distinct_key | distinct_key | 12 | func | 1 | |
| 2 | MATERIALIZED | de | index | PRIMARY | ix_fromdate | 3 | NULL | 331143 | Using index |
+------+--------------+-------------+--------+---------------+--------------+---------+------+--------+-------------+
SET optimizer_switch='materialization=off';
EXPLAIN
SELECT *
FROM departments d -- 9건
WHERE d.dept_no IN (SELECT de.dept_no
FROM dept_emp de -- 33만건
)
;
+------+-------------+-------+-------+---------------+-------------+---------+---------------------+-------+----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+-------------+---------+---------------------+-------+----------------------------+
| 1 | PRIMARY | d | index | PRIMARY | ux_deptname | 122 | NULL | 9 | Using index |
| 1 | PRIMARY | de | ref | PRIMARY | PRIMARY | 12 | employees.d.dept_no | 20696 | Using index; FirstMatch(d) |
+------+-------------+-------+-------+---------------+-------------+---------+---------------------+-------+----------------------------+
SET optimizer_switch='FirstMatch=off';
EXPLAIN
SELECT *
FROM departments d -- 9건
WHERE d.dept_no IN (SELECT de.dept_no
FROM dept_emp de -- 33만건
)
;
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+------------------------+
| 1 | PRIMARY | de | index | PRIMARY | PRIMARY | 16 | NULL | 331143 | Using index; LooseScan |
| 1 | PRIMARY | d | eq_ref | PRIMARY | PRIMARY | 12 | employees.de.dept_no | 1 | |
+------+-------------+-------+--------+---------------+---------+---------+----------------------+--------+------------------------+
SELECT * FROM t1 WHERE c IN (SELECT key1 FROM t2 WHERE ...);
SELECT * FROM t1 WHERE c IN (SELECT key2 FROM t2 WHERE key1 = '상수' AND ...);
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT s.emp_no
FROM salaries s
WHERE s.salary > 150000
)
;
+------+--------------+-------------+--------+-------------------+-----------+---------+--------------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------+-------------+--------+-------------------+-----------+---------+--------------------+------+--------------------------+
| 1 | PRIMARY | <subquery2> | ALL | distinct_key | NULL | NULL | NULL | 36 | |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.s.emp_no | 1 | |
| 2 | MATERIALIZED | s | range | PRIMARY,ix_salary | ix_salary | 4 | NULL | 36 | Using where; Using index |
+------+--------------+-------------+--------+-------------------+-----------+---------+--------------------+------+--------------------------+
SET optimizer_switch='materialization=off';
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT s.emp_no
FROM salaries s
WHERE s.salary > 150000
)
;
+------+-------------+-------+--------+-------------------+-----------+---------+--------------------+------+-------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+-------------------+-----------+---------+--------------------+------+-------------------------------------------+
| 1 | PRIMARY | s | range | PRIMARY,ix_salary | ix_salary | 4 | NULL | 36 | Using where; Using index; Start temporary |
| 1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | employees.s.emp_no | 1 | End temporary |
+------+-------------+-------+--------+-------------------+-----------+---------+--------------------+------+-------------------------------------------+
SELECT *
FROM t
WHERE expr1 IN (SELECT ...)
OR expr2
;
SELECT *
FROM t
WHERE expr1 NOT IN (SELECT ...)
;
SELECT (SELECT ...)
FROM t
;
SELECT *
FROM t
HAVING expr1 IN (SELECT ...)
;
SELECT *
FROM t
WHERE expr1 IN (SELECT ... UNION SELECT ...)
EXPLAIN EXTENDED
SELECT *
FROM employees e
WHERE e.emp_no IN (SELECT de.emp_no
FROM dept_emp de
WHERE de.dept_no = 'd009'
)
OR e.first_name = 'Matt'
;
+------+--------------------+-------+--------+---------------------------------------+---------+---------+------------+--------+----------+------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+--------------------+-------+--------+---------------------------------------+---------+---------+------------+--------+----------+------------------------+
| 1 | PRIMARY | e | ALL | ix_firstname | NULL | NULL | NULL | 299423 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | de | eq_ref | PRIMARY,ix_fromdate,ix_empno_fromdate | PRIMARY | 16 | const,func | 1 | 100.00 | Using where; Usingndex |
+------+--------------------+-------+--------+---------------------------------------+---------+---------+------------+--------+----------+------------------------+
2 rows in set, 1 warning (0.00 sec)
MariaDB [employees]> SHOW WARNINGS;
+-------+------+---------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------------------------------+
| Note | 1003 | select `employees`.`e`.`emp_no` AS `emp_no` |
| | | , `employees`.`e`.`birth_date` AS `birth_date` |
| | | , `employees`.`e`.`first_name` AS `first_name` |
| | | , `employs`.`e`.`last_name` AS `last_name` |
| | | , `employees`.`e`.`gender` AS `gender` |
| | | , `employees`.`e`.`hire_date` AS `hire_date` |
| | | from `employees`.`employees` `e` |
| | | where (<expcache><`employees`.`e`.`emp_no`>(<in_optimizer>(`employees`.`e`.`emp_no`, |
| | | <exists>(select `employees`.`de`.`emp_no` |
| | | from `employees`.`dept_emp` `de` |
| | | where ((`eloyees`.`de`.`dept_no` = 'd009') |
| | | and (<cache>(`employees`.`e`.`emp_no`) = `employees`.`de`.`emp_no`))))) |
| | | or (`employees`.`e`.`first_name` = 'Matt')) |
+-------+------+---------------------------------------------------------------------------------------+
- 강좌 URL : http://www.gurubee.net/lecture/4199
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.