mysql> explain
-> select *
-> from employees e
-> inner join salaries s on s.emp_no=e.emp_no
-> where first_name='ABC';
+----+-------------+-------+------------+------+----------------------+--------------+---------+--------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+----------------------+--------------+---------+--------------------+------+----------+-------+
| 1 | SIMPLE | e | NULL | ref | PRIMARY,ix_firstname | ix_firstname | 58 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | s | NULL | ref | PRIMARY | PRIMARY | 4 | employees.e.emp_no | 9 | 100.00 | NULL |
+----+-------------+-------+------------+------+----------------------+--------------+---------+--------------------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
MySQL 8.0 ๋ถํฐ๋ EXPLAIN ๋ช
๋ น ๊ฒฐ๊ณผ๋ก ์ถ๋ ฅ๋๋ ์คํ ๊ณํ ํฌ๋งท์ ๊ธฐ์กด ํ
์ด๋ธ ํฌ๋งท๊ณผ JSON, TREE ํํ๋ก ์ ํํ ์ ์๋ค.
์๋ฌด๋ฐ ์ต์
์์ด EXPLAIN ๋ช
๋ น์ ์คํํ๋ฉด ์ฟผ๋ฆฌ ๋ฌธ์ฅ์ ํน์ฑ์ ๋ฐ๋ผ ํ ํํ๋ก 1์ค ์ด์์ ๊ฒฐ๊ณผ๊ฐ ํ์๋๋ค.
ํ์ ๊ฐ ๋ ์ฝ๋๋ ์ฟผ๋ฆฌ ๋ฌธ์ฅ์์ ์ฌ์ฉ๋ ํ
์ด๋ธ์ ๊ฐ์๋งํผ ์ถ๋ ฅ๋๋ค.
์คํ ๊ณํ์ ์์์ ์๋๋ก ์์๋๋ก ํ์๋๋ค.(UNION์ด๋ ์๊ด ์๋ธ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ ์์๋๋ก ํ์๋์ง ์์ ์ ์์)
์ถ๋ ฅ๋ ์คํ ๊ณํ์์ ์์ชฝ์ ์ถ๋ ฅ๋ ๊ฒฐ๊ณผ์ผ์๋ก ์ฟผ๋ฆฌ์ ๋ฐ๊นฅ ๋ถ๋ถ์ด๊ฑฐ๋ ๋จผ์ ์ ๊ทผํ ํ
์ด๋ธ์ด๋ค.
ํ๋์ SELECT ๋ฌธ์ฅ์ ๋ค์ 1๊ฐ ์ด์์ ํ์ SELECT ๋ฌธ์ฅ์ ํฌํจํ ์ ์๋ค.
์คํ ๊ณํ์์ ๊ฐ์ฅ ์ผ์ชฝ์ ํ์๋๋ id ์นผ๋ผ์ ๋จ์ SELECT ์ฟผ๋ฆฌ๋ณ๋ก ๋ถ์ฌ๋๋ ์๋ณ์ ๊ฐ์ด๋ค.
ํ๋์ SELECT ๋ฌธ์ฅ ์์์ ์ฌ๋ฌ ๊ฐ์ ํ ์ด๋ธ์ ์กฐ์ธํ๋ฉด ์กฐ์ธ๋๋ ํ ์ด๋ธ์ ๊ฐ์๋งํผ ์คํ ๊ณํ ๋ ์ฝ๋๊ฐ ์ถ๋ ฅ๋์ง๋ง ๊ฐ์ id ๊ฐ์ด ๋ถ์ฌ๋๋ค.
mysql> explain
-> select
-> ( (select count(*) from employees) + (select count(*) from departments) ) as total_count;
+----+-------------+-------------+------------+-------+---------------+-------------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+-------+---------------+-------------+---------+------+--------+----------+----------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 3 | SUBQUERY | departments | NULL | index | NULL | ux_deptname | 162 | NULL | 9 | 100.00 | Using index |
| 2 | SUBQUERY | employees | NULL | index | NULL | ix_hiredate | 3 | NULL | 299969 | 100.00 | Using index |
+----+-------------+-------------+------------+-------+---------------+-------------+---------+------+--------+----------+----------------+
3 rows in set, 1 warning (0.00 sec)
์ ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์ ๊ฒฝ์ฐ ์ฟผ๋ฆฌ ๋ฌธ์ฅ์ด 3๊ฐ์ ๋จ์ select ์ฟผ๋ฆฌ๋ก ๊ตฌ์ฑ๋ผ ์์ผ๋ฏ๋ก ์คํ ๊ณํ์ ๊ฐ ๋ ์ฝ๋๊ฐ ๊ฐ๊ธฐ ๋ค๋ฅธ id๊ฐ์ ์ง๋๋ค.
mysql> explain
-> select * from dept_emp de
-> where de.emp_no= (select e.emp_no
-> from employees e
-> where e.first_name='Georgi'
-> and e.last_name='Facello' limit 1);
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------------+
| 1 | PRIMARY | de | NULL | ref | ix_empno_fromdate | ix_empno_fromdate | 4 | const | 1 | 100.00 | Using where |
| 2 | SUBQUERY | e | NULL | ref | ix_firstname | ix_firstname | 58 | const | 253 | 10.00 | Using where |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
์ฃผ์ํ ์ ์ ์คํ ๊ณํ์ id ์นผ๋ผ์ด ํ ์ด๋ธ์ ์ ๊ทผ ์์๋ฅผ ์๋ฏธํ์ง๋ ์๋๋ค๋ ๊ฒ์ด๋ค. ์ ์ฟผ๋ฆฌ๋ employees ํ ์ด๋ธ์ ๋จผ์ ์ฝ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ dept_emp ํ ์ด๋ธ๊ณผ ์กฐ์ธํจ์๋ ๋ถ๊ตฌํ๊ณ id๊ฐ ์์์ ์ผ์นํ์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
select_type ์นผ๋ผ์์๋ ๊ฐ ๋จ์ select ์ฟผ๋ฆฌ๊ฐ ์ด๋ค ํ์ ์ ์ฟผ๋ฆฌ์ธ์ง ํ์๋๋ ์นผ๋ผ์ด๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ฐ๋ค์ด ํ์๋ ์ ์๋ค.
SIMPLE
- UNION์ด๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๋จ์ํ SELECT ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ SIMPLE๋ก ํ์๋๋ค(์กฐ์ธ๋ ๋ง์ฐฌ๊ฐ์ง).
- ์ฟผ๋ฆฌ ๋ฌธ์ฅ์ด ์๋ฌด๋ฆฌ ๋ณต์กํ๋๋ผ๋ ์คํ ๊ณํ์์ SIMPLE์ธ ๋จ์ SELECT ์ฟผ๋ฆฌ๋ ๋จ ํ๋๋ง ์กด์ฌํ๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฅ ๋ฐ๊นฅ SELECT ์ฟผ๋ฆฌ๊ฐ SIMPLE๋ก ํ์๋๋ค.
PRIMARY
- UNION์ด๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ง๋ SELECT ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ์ ์๋ ๋จ์ SELECT ์ฟผ๋ฆฌ๋ PRIMARY๋ก ํ์๋๋ค.
- SIMPLE๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก PRIMARY์ธ ๋จ์ SELECT ์ฟผ๋ฆฌ๋ ํ๋๋ง ์กด์ฌํ๋ค.
UNION
- UINON์ผ๋ก ๊ฒฐํฉํ๋ ๋จ์ SELECT ์ฟผ๋ฆฌ ๊ฐ์ด๋ฐ
์ฒซ ๋ฒ์งธ๋ฅผ ์ ์ธํ ๋ ๋ฒ์งธ ์ดํ ๋จ์ SELECT
์ฟผ๋ฆฌ๋ UNION์ผ๋ก ํ์๋๋ค. - UNION์ ์ฒซ ๋ฒ์งธ ๋จ์ SELECT ์ฟผ๋ฆฌ๋ UNION์ด ์๋๋ผ UNION๋๋ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ค์ ๋ชจ์ ์ ์ฅํ๋ ์์ ํ ์ด๋ธ DERIVED๊ฐ ํ์๋๋ค.
- UINON์ผ๋ก ๊ฒฐํฉํ๋ ๋จ์ SELECT ์ฟผ๋ฆฌ ๊ฐ์ด๋ฐ
DEPENDENT_UNION
- DEPENDENT๋ UNION์ด๋ UNION ALL๋ก ๊ฒฐํฉ๋ ๋จ์ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ถ ์ฟผ๋ฆฌ์ ์ํฅ์ ๋ฐ๋ ๊ฒ์ ์๋ฏธํ๋ค.
-
mysql> explain -> select * -> from employees e1 where e1.emp_no in ( -> select e2.emp_no from employees e2 where e2.first_name='Matt' -> union -> select e3.emp_no from employees e3 where e3.last_name='Matt' -> ); +----+--------------------+------------+------------+--------+----------------------+---------+---------+------+--------+----------+-----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+------------+------------+--------+----------------------+---------+---------+------+--------+----------+-----------------+ | 1 | PRIMARY | e1 | NULL | ALL | NULL | NULL | NULL | NULL | 299969 | 100.00 | Using where | | 2 | DEPENDENT SUBQUERY | e2 | NULL | eq_ref | PRIMARY,ix_firstname | PRIMARY | 4 | func | 1 | 5.00 | Using where | | 3 | DEPENDENT UNION | e3 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | 10.00 | Using where | | 4 | UNION RESULT | <union2,3> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------------+------------+------------+--------+----------------------+---------+---------+------+--------+----------+-----------------+
- ์ ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ ์ตํฐ๋ง์ด์ ๊ฐ ์ธ๋ถ์ employees ํ ์ด๋ธ์ ๋จผ์ ์ฝ์ ๋ค์ ์๋ธ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋๋ฐ, ์ด ๋ employees ํ ์ด๋ธ์ ์นผ๋ผ ๊ฐ์ด ์๋ธ์ฟผ๋ฆฌ์ ์ํฅ์ ์ค๋ค.
- ์ด๋ ๊ฒ ๋ด๋ถ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ถ์ ๊ฐ์ ์ฐธ์กฐํด์ ์ฒ๋ฆฌ๋ ๋ DEPENDENT ํค์๋๊ฐ ํ์๋๋ค.
- ๋ด๋ถ์ ์ผ๋ก๋ UNION์ ์ฌ์ฉ๋ SELECT ์ฟผ๋ฆฌ์ WHERE ์กฐ๊ฑด์ e2.emp_no=e1.emp_no์ e3.emp_no=e1.emp_no๋ผ๋ ์กฐ๊ฑด์ด ์๋์ผ๋ก ์ถ๊ฐ๋์ด ์คํ๋๋ค.
- ์ธ๋ถ์ ์ ์๋ employees ํ ์ด๋ธ์ emp_no ์นผ๋ผ์ด ์๋ธ์ฟผ๋ฆฌ์ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ DEPENDENT UNION์ด ํ์๋๋ ๊ฒ์ด๋ค.
UNION RESULT
- UNION RESULT๋ UNION ๊ฒฐ๊ณผ๋ฅผ ๋ด์๋๋ ํ ์ด๋ธ์ ์๋ฏธํ๋ค.
- 8.0 ๋ฒ์ ๋ถํฐ UNION ALL์ ๊ฒฝ์ฐ ์์ ํ ์ด๋ธ์ ์ฌ์ฉํ์ง ์๋๋ก ๊ธฐ๋ฅ์ด ๊ฐ์ ๋์ง๋ง, UNION(๋๋ UNION DISTINCT)์ ์ฌ์ ํ ์์ ํ ์ด๋ธ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฒํผ๋งํ๋ค.
- ์ด ์์ ํ ์ด๋ธ์ ๊ฐ๋ฆฌํค๋ select_type์ด UNION RESULT ์ด๊ณ , ์ค์ ์ฟผ๋ฆฌ์ ๋จ์ ์ฟผ๋ฆฌ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋ณ๋์ id ๊ฐ์ ๋ถ์ฌ๋์ง ์๋๋ค.
- UNION ๋์ UNION ALL์ ์ฌ์ฉํ ๊ฒฝ์ฐ ํด๋น ์คํ ๊ณํ ๋ ์ฝ๋๋ ๋ณด์ด์ง ์๊ฒ ๋๋ค.
SUBQUERY
- select_type์
SUBQUERY๋ FROM์ ์ด์ธ
์์ ์ฌ์ฉ๋๋ ์๋ธ์ฟผ๋ฆฌ๋ง์ ์๋ฏธํ๋ค. - MySQL ์๋ฒ์ ์คํ ๊ณํ์์
FROM ์ ์ ์ฌ์ฉ๋ ์๋ธ์ฟผ๋ฆฌ๋ DERIVED
๋ก ํ์๋๊ณ ,๊ทธ ๋ฐ์ ์์น์์ ์ฌ์ฉ๋ ์๋ธ์ฟผ๋ฆฌ๋ ์ ๋ถ SUBQUERY
๋ผ๊ณ ํ์๋๋ค. - ์๋ธ์ฟผ๋ฆฌ๋ ์ฌ์ฉํ๋ ์์น์ ๋ฐ๋ผ ๊ฐ๊ฐ ๋ค๋ฅธ ์ด๋ฆ์ ์ง๋๊ณ ์๋ค.
์ค์ฒฉ๋ ์ฟผ๋ฆฌ(Nested Query)
: SELECT๋๋ ์นผ๋ผ์ ์ฌ์ฉ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋ค์คํฐ๋ ์ฟผ๋ฆฌ๋ผ๊ณ ํ๋ค.์๋ธ์ฟผ๋ฆฌ(Subquery)
: WHERE ์ ์ ์ฌ์ฉ๋ ๊ฒฝ์ฐ์๋ ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ฅ ์๋ธ์ฟผ๋ฆฌ๋ผ๊ณ ํ๋ค.ํ์ ํ ์ด๋ธ(Derived Query)
: FROM ์ ์ ์ฌ์ฉ๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ MySQL์์๋ ํ์ ํ ์ด๋ธ์ด๋ผ๊ณ ํ๋ฉฐ, ์ผ๋ฐ์ ์ผ๋ก RDBMS์์๋ ์ธ๋ผ์ธ ๋ทฐ, ๋๋ ์๋ธ ์ ๋ ํธ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
- ๋ํ ์๋ธ์ฟผ๋ฆฌ๊ฐ ๋ฐํํ๋ ๊ฐ์ ํน์ฑ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ๋ถํ๊ธฐ๋ ํ๋ค.
์ค์นผ๋ผ ์๋ธ์ฟผ๋ฆฌ(Scalar Subquery)
: ํ๋์ ๊ฐ๋ง(์นผ๋ผ์ด ๋จ ํ๋์ธ ๋ ์ฝ๋ 1๊ฑด๋ง) ๋ฐํํ๋ ์ฟผ๋ฆฌ๋ก์ฐ ์๋ธ์ฟผ๋ฆฌ(Row Subquery)
: ์นผ๋ผ์ ๊ฐ์์ ๊ด๊ณ์์ด ํ๋์ ๋ ์ฝ๋๋ง ๋ฐํํ๋ ์ฟผ๋ฆฌ
- select_type์
DEPENDENT SUBQUERY
- ์๋ธ์ฟผ๋ฆฌ๊ฐ ๋ฐ๊นฅ์ชฝ SELECT ์ฟผ๋ฆฌ์์ ์ ์๋ ์นผ๋ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ DEPENDENT SUBQUERY๋ผ๊ณ ํ์๋๋ค.
-
mysql> 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.first_name='Matt'; +----+--------------------+-------+------------+------+---------------------------+-------------------+---------+----------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+-------+------------+------+---------------------------+-------------------+---------+----------------------+------+----------+-------------+ | 1 | PRIMARY | e | NULL | ref | ix_firstname | ix_firstname | 58 | const | 233 | 100.00 | Using index | | 2 | DEPENDENT SUBQUERY | de | NULL | ref | PRIMARY,ix_empno_fromdate | ix_empno_fromdate | 4 | employees.e.emp_no | 1 | 100.00 | Using index | | 2 | DEPENDENT SUBQUERY | dm | NULL | ref | PRIMARY | PRIMARY | 16 | employees.de.dept_no | 2 | 100.00 | Using index | +----+--------------------+-------+------------+------+---------------------------+-------------------+---------+----------------------+------+----------+-------------+
- ๋ํ DEPENDENT UNION๊ณผ ๊ฐ์ด DEPENDENT SUBQUERY ๋ํ ์ธ๋ถ ์ฟผ๋ฆฌ๊ฐ ๋จผ์ ์ํ๋ ํ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์คํ๋ผ์ผ ํ๋ฏ๋ก DEPENDENT ํค์๋๊ฐ ์๋ ์ผ๋ฐ ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค๋ ์ฒ๋ฆฌ์๋๊ฐ ๋๋ฆด ๋๊ฐ ๋ง๋ค.
DERIVED
- DERIVED๋ ๋จ์ SELECT ์ฟผ๋ฆฌ์ ์คํ ๊ฒฐ๊ณผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ ๋์คํฌ์ ์์ ํ ์ด๋ธ์ ์์ฑํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
- 5.5 ๋ฒ์ ๊น์ง๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ FROM์ ์ ์ฌ์ฉ๋ ๊ฒฝ์ฐ ํญ์ select_type์ด DERIVED์์ง๋ง, 5.6 ๋ฒ์ ๋ถํฐ ์ตํฐ๋ง์ด์ ์ต์ ์ ๋ฐ๋ผ FROM ์ ์ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์ธ๋ถ ์ฟผ๋ฆฌ์ ํตํฉํ๋ ํํ์ ์ต์ ํ๊ฐ ์ํ๋๊ธฐ๋ ํ๋ค.
- 5.5 ๋ฒ์ ๊น์ง๋ ํ์ ํ ์ด๋ธ์ ์ธ๋ฑ์ค๊ฐ ์ ํ ์์ผ๋ฏ๋ก ๋ค๋ฅธ ํ ์ด๋ธ๊ณผ ์กฐ์ธํ ๋ ์ฑ๋ฅ์ ๋ถ๋ฆฌํ ๋๊ฐ ๋ง์๋๋ฐ, 5.6 ๋ฒ์ ๋ถํฐ ์ตํฐ๋ง์ด์ ์ต์ ์ ๋ฐ๋ผ ์ฟผ๋ฆฌ์ ํน์ฑ์ ๋ง๊ฒ ์์ ํ ์ด๋ธ์๋ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค ์ ์๊ฒ ์ต์ ํ ๋๋ค.
- MySQL ์๋ฒ๋ ๋ฒ์ ์ด ์ ๊ทธ๋ ์ด๋๋๋ฉด์ ์กฐ์ธ ์ฟผ๋ฆฌ์ ๋ํ ์ต์ ํ๋ ๋ง์ด ์ฑ์๋ ์ํ์ด๋ฏ๋ก ํ์ ํ ์ด๋ธ์ ๋ํ ์ต์ ํ๊ฐ ๋ถ์กฑํ MySQL ์๋ฒ๋ฅผ ์ฌ์ฉ ์ค์ผ ๊ฒฝ์ฐ, ๊ฐ๋ฅํ๋ค๋ฉด DERIVED ํํ์ ์คํ ๊ณํ์ ์กฐ์ธ์ผ๋ก ํด๊ฒฐํ ์ ์๊ฒ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด ์ข๋ค.
- 8.0 ๋ฒ์ ๋ถํฐ๋ FROM ์ ์ ์๋ธ์ฟผ๋ฆฌ์ ๋ํ ์ต์ ํ๋ ๋ง์ด ๊ฐ์ ๋์ด ๊ฐ๋ฅํ๋ค๋ฉด ๋ถํ์ํ ์๋ธ์ฟผ๋ฆฌ๋ ์กฐ์ธ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ฌ์์ฑํด์ ์ฒ๋ฆฌํ๋ค.
-
์ฟผ๋ฆฌ๋ฅผ ํ๋ํ๊ธฐ ์ํด ์คํ ๊ณํ์ ํ์ธํ ๋ ๊ฐ์ฅ ๋จผ์ select_type ์นผ๋ผ์ ๊ฐ์ด DERIVED์ธ ๊ฒ์ด ์๋์ง ํ์ธํด์ผ ํ๋ค. ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ธ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค๋ ์กฐ์ธ์ ์ฌ์ฉํ ๊ฒ์ ๊ฐ๋ ฅํ ๊ถ์ฅํ๋ค.
DEPENDENT DERIVED
- 8.0 ์ด์ ๋ฒ์ ์์๋ FROM ์ ์ ์๋ธ์ฟผ๋ฆฌ๋ ์ธ๋ถ ์นผ๋ผ์ ์ฌ์ฉํ ์ ์์๋๋ฐ, 8.0 ๋ฒ์ ๋ถํฐ ๋ํฐ๋ด ์กฐ์ธ(LATERAL JOIN) ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์๋ค.
- DEPENDENT DERIVED ํค์๋๋ ํด๋น ํ ์ด๋ธ์ด ๋ํฐ๋ด ์กฐ์ธ์ผ๋ก ์ฌ์ฉ๋ ๊ฒ์ ์๋ฏธํ๋ค.
UNCACHEABLE SUBQUERY
- ํ๋์ ์ฟผ๋ฆฌ ๋ฌธ์ฅ์ ์๋ธ ์ฟผ๋ฆฌ๊ฐ ํ๋๋ง ์๋๋ผ๋ ์ค์ ๋ก ๊ทธ ์๋ธ์ฟผ๋ฆฌ๊ฐ ํ ๋ฒ๋ง ์คํ๋๋๊ฒ ์๋
- ๊ทธ๋ฐ๋ฐ ์กฐ๊ฑด์ด ๋๊ฐ์ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์คํ๋ ๋๋ ๋ค์ ์คํํ์ง ์๊ณ ์ด์ ์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๊ฒ ์๋ธ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ถ์ ์ธ ์บ์ ๊ณต๊ฐ์ ๋ด์๋๋ค.
- select_type์ด SUBQUERY์ธ ๊ฒฝ์ฐ์ UNCACHEABLE SUBQUERY๋ ์ด ์บ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ ์๋๋์ ์ฐจ์ด๊ฐ ์๋ค.
- ์๋ธ์ฟผ๋ฆฌ์ ํฌํจ๋ ์์์ ์ํด ์บ์ ์์ฒด๊ฐ ๋ถ๊ฐ๋ฅํ ์๊ฐ ์๋๋ฐ, ๊ทธ๋ด ๊ฒฝ์ฐ select_type์ด UNCACHEABLE SUBQUERY๋ก ํ์๋๋ค.
UNCACHEABLE UNION
MATERIALIZED
- ์ฃผ๋ก FROM ์ ์ด๋ IN ํํ์ ์ฟผ๋ฆฌ์ ์ฌ์ฉ๋ ์๋ธ์ฟผ๋ฆฌ์ ์ต์ ํ๋ฅผ ์ํด ์ฌ์ฉ๋๋ค.
-
mysql> explain -> select * -> from employees e -> where e.emp_no in (select emp_no from salaries where salary between 100 and 1000); +----+--------------+-------------+------------+--------+-------------------+-----------+---------+--------------------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+-------------+------------+--------+-------------------+-----------+---------+--------------------+------+----------+--------------------------+ | 1 | SIMPLE | <subquery2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | 100.00 | NULL | | 1 | SIMPLE | e | NULL | eq_ref | PRIMARY | PRIMARY | 4 | <subquery2>.emp_no | 1 | 100.00 | NULL | | 2 | MATERIALIZED | salaries | NULL | range | PRIMARY,ix_salary | ix_salary | 4 | NULL | 1 | 100.00 | Using where; Using index | +----+--------------+-------------+------------+--------+-------------------+-----------+---------+--------------------+------+----------+--------------------------+ 3 rows in set, 1 warning (0.00 sec)
MySQL ์๋ฒ์ ์คํ ๊ณํ์ ๋จ์ SELECT ์ฟผ๋ฆฌ ๊ธฐ์ค์ด ์๋๋ผ ํ
์ด๋ธ ๊ธฐ์ค์ผ๋ก ํ์๋๋ค.
ํ
์ด๋ธ์ ์ด๋ฆ์ ๋ณ์นญ์ด ๋ถ์ฌ๋ ๊ฒฝ์ฐ์๋ ๋ณ์นญ์ด ํ์๋๋ค.
mysql> explain select now();
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
mysql> explain select now() from dual;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
์ค์ DUAL์ด๋ผ๋ ํ
์ด๋ธ์ ์์ง๋ง ์ค๋ผํด RDBMS์ ์ต์ํ ์ฌ์ฉ์๋ฅผ ์ํด MySQL ์๋ฒ๋ ๋ด๋ถ์ ์ผ๋ก DUAL์ด๋ผ๋ ํ
์ด๋ธ์ด ์๋ ๊ฒ ์ฒ๋ผ ์๋ํ๋ค.
์ค๋ผํด RDBMS์์๋ FROM ์ ์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง MySQL ์๋ฒ๋ ๊ทธ๋ ์ง ์๋ค.
๋ณ๋์ ํ
์ด๋ธ์ ์ฌ์ฉํ์ง ์๋ SELECT ์ฟผ๋ฆฌ์ธ ๊ฒฝ์ฐ ์์ ๊ฐ์ด NULL์ด ํ์๋๋ค.
<derived N>
๋๋ <union M,N>
๊ณผ ๊ฐ์ด <>๋ก ๋๋ฌ์ธ์ธ ํ
์ด๋ธ์ ์์ ํ
์ด๋ธ์ ์๋ฏธํ๋ค.
๋ง์ฝ <derived 2>
์ด๋ฉด ๋จ์ SELECT ์ฟผ๋ฆฌ์ id ๊ฐ์ด 2์ธ ์คํ ๊ณํ์ผ๋ก๋ถํฐ ๋ง๋ค์ด์ง ํ์ ํ
์ด๋ธ์ ๊ฐ๋ฆฌํจ๋ค.
+----+-------------+------------+------------+--------+---------------------------------------+-------------------+---------+-----------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------------------------------+-------------------+---------+-----------+--------+----------+-------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 331143 | 100.00 | NULL |
| 1 | PRIMARY | e | NULL | eq_ref | PRIMARY | PRIMARY | 4 | tb.emp_no | 1 | 100.00 | NULL |
| 2 | DERIVED | de | NULL | index | PRIMARY,ix_fromdate,ix_empno_fromdate | ix_empno_fromdate | 7 | NULL | 331143 | 100.00 | Using index |
+----+-------------+------------+------------+--------+---------------------------------------+-------------------+---------+-----------+--------+----------+-------------+
- ์ฒซ ๋ฒ์งธ ๋ผ์ธ์ ํ ์ด๋ธ์ด ๋ผ๋ ๊ฒ์ ๋ณด์ ์ด ๋ผ์ธ๋ณด๋ค id ๊ฐ์ด 2์ธ ๋ผ์ธ์ด ๋จผ์ ์คํ๋๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํ์ ํ ์ด๋ธ๋ก ์ค๋น๋ผ์ผ ํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
- id ๊ฐ์ด 2์ธ ๋ผ์ธ์ ๋ณด๋ฉด select_type์ด derived์ด๊ณ , table์ด de์ธ ํ ์ด๋ธ์ ์ฝ์ด์ ํ์ ํ ์ด๋ธ์ ์์ฑํ๋ ๊ฒ์ ์ ์ ์๋ค.
- ์ฒซ ๋ฒ์งธ ๋ผ์ธ๊ณผ ๋ ๋ฒ์งธ ๋ผ์ธ์ด ๊ฐ์ id ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ผ๋ก ๋ด์ ์ e ํ ์ด๋ธ์ด ์กฐ์ธ๋๋ ์ฟผ๋ฆฌ๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
- ๊ทธ๋ฐ๋ฐ ํ ์ด๋ธ์ด e ํ ์ด๋ธ๋ณด๋ค ๋จผ์ ํ์๋๊ธฐ ๋๋ฌธ์ ๊ฐ ๋๋ผ์ด๋น ํ ์ด๋ธ์ด ๋๊ณ , e ํ ์ด๋ธ์ด ๋๋ฆฌ๋ธ ํ ์ด๋ธ์ด ๋๋ ๊ฒ์ ์ ์ ์๋ค.
- ์ฆ ํ ์ด๋ธ์ ๋จผ์ ์ฝ๊ณ e ํ ์ด๋ธ๋ก ์กฐ์ธ์ ์คํํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
mysql> explain
-> select *
-> from (select de.emp_no from dept_emp de group by de.emp_no) tb, employees e
-> where e.emp_no=tb.emp_no;
partitions ์ปฌ๋ผ์ ํตํด ํํฐ์
์ด ์ฌ๋ฌ ๊ฐ์ธ ํ
์ด๋ธ์์ ๋ถํ์ํ ํํฐ์
์ ์ ์ธํ๊ณ , ์ฟผ๋ฆฌ๋ฅผ ์ํํ๊ธฐ ์ํด ์ ๊ทผํด์ผ ํ ๊ฒ์ผ๋ก ํ๋จ๋๋ ํ
์ด๋ธ๋ง ๊ณจ๋ผ๋ผ ์ ์๋ค.
์ด๋ฌํ ๊ณผ์ ์ ํํฐ์
ํ๋ฃจ๋์ด๋ผํ๋ค.
์ฟผ๋ฆฌ ์คํ ๊ณํ์์ type ์ดํ์ ์นผ๋ผ์ MySQL ์๋ฒ๊ฐ ๊ฐ ํ
์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ด๋ค ๋ฐฉ์์ผ๋ก ์ฝ์๋์ง๋ฅผ ๋ํ๋ธ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ํ๋ํ ๋ ์ธ๋ฑ์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๋์ง ํ์ธํ๋ ๊ฒ์ด ์ค์ํ๋ฏ๋ก type ์นผ๋ผ์ ๋งค์ฐ ์ค์ํ ์ ๋ณด
- system
- const
- eq_ref
- ref
- fulltext
- ref_or_null
- unique_subquery
- index_subquery
- range
- index_merge
- index
- ALL
์ ์ ๊ทผ ๋ฐฉ๋ฒ ์ค์์ ALL์ ํํ
์ด๋ธ ์ค์บ์ ์๋ฏธํ๊ณ , ๋๋จธ์ง๋ ๋ชจ๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๋ค.
๋ํ ์ฑ๋ฅ์ด ๋น ๋ฅธ ์์๋๋ก ๋์ดํ ๊ฒ์ด๋ค.
๋ ์ฝ๋๊ฐ 1๊ฑด๋ง ์กด์ฌํ๋ ํ ์ด๋ธ ๋๋ ํ ๊ฑด๋ ์กด์ฌํ์ง ์๋ ํ ์ด๋ธ์ ์ฐธ์กฐํ๋ ํํ์ ์ ๊ทผ ๋ฐฉ๋ฒ์ system์ด๋ผ ํ๋ค.
์ฟผ๋ฆฌ๊ฐ ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ ์ ๋ํฌ ํค ์นผ๋ผ์ ์ด์ฉํ๋ where ์กฐ๊ฑด์ ์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ๋ฐ๋์ 1๊ฑด์ ๋ฐํํ๋ ์ฒ๋ฆฌ ๋ฐฉ์์ const๋ผ๊ณ ํ๋ค.
๋ค์ค ์นผ๋ผ์ผ๋ก ๊ตฌ์ฑ๋ ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ ์ ๋ํฌ ํค ์ค ์ธ๋ฑ์ค์ ์ผ๋ถ ์นผ๋ผ๋ง ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ const ํ์
์ ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
ํ๋ผ์ด๋จธ๋ฆฌ ํค์ ์ผ๋ถ๋ง ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉํ ๋๋ const๊ฐ ์๋ ref๋ก ํ์๋๊ณ , ๋ชจ๋ ์นผ๋ผ์ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉํ๋ฉด const ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
MySQL์ ์ตํฐ๋ง์ด์ ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ๋ ๋จ๊ณ์์ ์ฟผ๋ฆฌ๋ฅผ ๋จผ์ ์คํํด์ ํต์งธ๋ก ์์ํํ๊ธฐ ๋๋ฌธ์ const์ด๋ค.
where first_name = (select first_name from employees e2 where emp_no=100001)
where first_name = 'Jasminko'
๋ก ์นํ๋๋ค.
eq_ref ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ํ
์ด๋ธ์ด ์กฐ์ธ๋๋ ์ฟผ๋ฆฌ์ ์คํ๊ณํ
์์๋ง ํ์๋๋ค.
์กฐ์ธ์์ ์ฒ์ ์ฝ์ ํ
์ด๋ธ์ ์นผ๋ผ๊ฐ์, ๊ทธ๋ค์ ์ฝ์ด์ผ ํ ํ
์ด๋ธ์ pk๋ ์ ๋ํฌ ํค ์นผ๋ผ์ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ์ฉํ ๋๋ฅผ ๊ฐ๋ฆฌ์ผ eq_ref๋ผ๊ณ ํ๋ค.
์ด ๋ ๋ ๋ฒ์งธ ์ดํ์ ์ฝ๋ ํ
์ด๋ธ์ type ์นผ๋ผ์ eq_ref๊ฐ ํ์๋๋ค.
๋ ๋ฒ์งธ ์ดํ์ ์ฝํ๋ ํ ์ด๋ธ์ ์ ๋ํฌ ํค๋ก ๊ฒ์ํ ๋ ๊ทธ ์ ๋ํฌ ์ธ๋ฑ์ค๋ NOT NULL์ด์ด์ผ ํ๋ฉฐ, ๋ค์ค ์นผ๋ผ์ผ๋ก ๋ง๋ค์ด์ง ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ ์ ๋ํฌ ์ธ๋ฑ์ค๋ผ๋ฉด ๋ชจ๋ ์นผ๋ผ์ด ๋น๊ต ์กฐ๊ฑด์ ์ฌ์ฉ๋ผ์ผ๋ง eq_ref ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์ฌ์ฉ๋ ์ ์๋ค.
์ฆ ์กฐ์ธ์์ ๋ ๋ฒ์งธ ์ดํ์ ์ฝ๋ ํ ์ด๋ธ์์ ๋ฐ๋์ 1๊ฑด๋ง ์กด์ฌํ๋ค๋ ๋ณด์ฅ์ด ์์ด์ผ ์ฌ์ฉํ ์ ์๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๋ค.
mysql> explain
-> select * from dept_emp de, employees e
-> where e.emp_no=de.emp_no AND de.dept_no='d005';
+----+-------------+-------+------------+--------+---------------------------+---------+---------+---------------------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------------------+---------+---------+---------------------+--------+----------+-------+
| 1 | SIMPLE | de | NULL | ref | PRIMARY,ix_empno_fromdate | PRIMARY | 16 | const | 165571 | 100.00 | NULL |
| 1 | SIMPLE | e | NULL | eq_ref | PRIMARY | PRIMARY | 4 | employees.de.emp_no | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------------------+---------+---------+---------------------+--------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
employees ํ ์ด๋ธ์ emp_no๋ pk๋ผ์ ์กฐ๊ฑด์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ 1๊ฑด๋ง ์กด์ฌํ๋ฏ๋ก eq_ref๊ฐ ํ์๋๋ ๊ฒ
ref ์ ๊ทผ ๋ฐฉ๋ฒ์ ์กฐ์ธ์ ์์์ ์๊ด์์ด ์ฌ์ฉ๋๋ฉฐ pk, ์ ๋ํฌ ํค ์กฐ๊ฑด๋ ์๋ค.
์ธ๋ฑ์ค ์ข
๋ฅ์ ์๊ด์์ด ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์ํ ๋ ref ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์ฌ์ฉ๋๋ค. ref ํ์
์ ๋ฐํ๋๋ ๋ ์ฝ๋๊ฐ ๋ฐ๋์ 1๊ฑด์ด๋ผ๋ ๋ณด์ฅ์ด ์์ผ๋ฏ๋ก const๋ eq_ref๋ณด๋ค ๋น ๋ฅด์ง ์๋ค.
ํ์ง๋ง ๋๋ฑ ์กฐ๊ฑด์ผ๋ก๋ง ๋น๊ต๋๋ฏ๋ก ๋งค์ฐ ๋น ๋ฅธ ๋ ์ฝ๋ ์กฐํ ๋ฐฉ๋ฒ์ค ํ๋.
mysql> explain
-> select * from dept_emp where dept_no='d005';
+----+-------------+----------+------------+------+---------------+---------+---------+-------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+--------+----------+-------+
| 1 | SIMPLE | dept_emp | NULL | ref | PRIMARY | PRIMARY | 16 | const | 165571 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+--------+----------+-------+
dept_emp ํ ์ด๋ธ์ pk๋ฅผ ๊ตฌ์ฑํ๋ ์นผ๋ผ (dept_no, emp_no) ์ค ์ผ๋ถ detp_no๋ง ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ๋์๊ธฐ ๋๋ฌธ์ ์กฐ๊ฑด์ ์ผ์นํ๋ ๋ ์ฝ๋๊ฐ 1๊ฑด์ด๋ผ๋ ๋ณด์ฅ์ด ์๋ค.
๊ทธ๋์ const๊ฐ ์๋ ref๊ฐ ์ฌ์ฉ๋์๋ค.
const
: ์กฐ์ธ์ ์์์ ๊ด๊ณ์์ด ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ ์ ๋ํฌ ํค์ ๋ชจ๋ ์นผ๋ผ์ ๋ํด ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์(๋ฐ๋์ 1๊ฑด ๋ ์ฝ๋ ๋ฐํ)eq_ref
: ์กฐ์ธ์์ ์ฒซ ๋ฒ์งธ ์ฝ์ ํ ์ด๋ธ์ ์นผ๋ผ๊ฐ์ ์ด์ฉํด ๋ ๋ฒ์งธ ํ ์ด๋ธ์ pk๋ ์ ๋ํฌ ํค๋ก ๋๋ฑ ์กฐ๊ฑด ๊ฒ์(๋ ๋ฒ์งธ ํ ์ด๋ธ์ ๋ฐ๋์ 1๊ฑด ๋ ์ฝ๋ ๋ฐํ)ref
: ์กฐ์ธ ์์๋ ์ธ๋ฑ์ค ์ข ๋ฅ์ ๊ด๊ณ์์ด ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์
์ ์ธ๊ฐ์ง ๋ชจ๋ ๋งค์ฐ ์ข์ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ์ธ๋ฑ์ค์ ๋ถํฌ๋๊ฐ ๋์์ง ์๋ค๋ฉด ์ฑ๋ฅ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์๋ ๋ฐฉ๋ฒ๋ค์ด๋ค.
์ฟผ๋ฆฌ๋ฅผ ํ๋ํ ๋๋ ์ด ์ธ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ๋ฒ์ ๋ํด์๋ ํฌ๊ฒ ์ ๊ฒฝ์ฐ์ง ์๊ณ ๋์ด๊ฐ๋ ๋ฌด๋ฐฉ
fulltext ์ ๊ทผ ๋ฐฉ๋ฒ์ MySQL ์๋ฒ์ ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉ
ํด ๋ ์ฝ๋๋ฅผ ์ฝ๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ ์๋ฏธํ๋ค.
MySQL ์๋ฒ์์ ์ ๋ฌธ ๊ฒ์ ์กฐ๊ฑด์ ์ฐ์ ์์๊ฐ ์๋นํ ๋๋ค. ์ฟผ๋ฆฌ์์ ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด๊ณผ ๊ทธ ์ด์ธ์ ์ผ๋ฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด์ ํจ๊ป ์ฌ์ฉํ๋ฉด
์ผ๋ฐ ์ธ๋ฑ์ค์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด const๋ eq_ref, ref๊ฐ ์๋๋ฉด ์ผ๋ฐ์ ์ผ๋ก MySQL์ ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด์ ์ ํํด์ ์ฒ๋ฆฌํ๋ค.
์ ๋ฌธ ๊ฒ์์ MATCH, AGAINST ๊ตฌ๋ฌธ์ ์ฌ์ฉํด์ ์คํํ๋๋ฐ, ์ด๋ ๋ฐ๋์ ํด๋น ํ
์ด๋ธ์ ์ ๋ฌธ ๊ฒ์์ฉ ์ธ๋ฑ์ค๊ฐ ์ค๋น๋ผ ์์ด์ผ๋ง ํ๋ค.
ํ
์ด๋ธ์ ์ ๋ฌธ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด ์ฟผ๋ฆฌ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ณ ์ค์ง๋ ๊ฒ์ด๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ฟผ๋ฆฌ์ ์ ๋ฌธ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ์ฉํ๋ฉด MySQL์ ์ฃผ์ ์์ด fulltext ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
ํ์ง๋ง ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ๋ fulltext๋ณด๋ค ์ผ๋ฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ range ์ ๊ทผ ๋ฐฉ๋ฒ์ด ๋ ๋นจ๋ฆฌ ์ฒ๋ฆฌ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฏ๋ก ์ ๋ฌธ ๊ฒ์ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋๋ ์กฐ๊ฑด๋ณ๋ก ์ฑ๋ฅ์ ํ์ธํด ๋ณด๋ ํธ์ด ์ข๋ค.
์ด ์ ๊ทผ ๋ฐฉ๋ฒ์ ref ์ ๊ทผ ๋ฐฉ๋ฒ๊ณผ ๊ฐ์๋ฐ, null ๋น๊ต๊ฐ ์ถ๊ฐ๋ ํํ
์ค์ ์
๋ฌด์์ ๋ง์ด ํ์ฉ๋์ง๋ ์์ง๋ง, ๋ง์ฝ ์ฌ์ฉ๋๋ค๋ฉด ๋์์ง ์์ ์ ๊ทผ ๋ฐฉ๋ฒ ์ ๋๋ก ๊ธฐ์ตํ์
where ์กฐ๊ฑด์ ์์ ์ฌ์ฉ๋ ์ ์๋ IN ํํ์ ์ฟผ๋ฆฌ๋ฅผ ์ํ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๋ค. ์ด๋ฆ ์๋ฏธ ๊ทธ๋๋ก ์๋ธ์ฟผ๋ฆฌ์์ ์ค๋ณต๋์ง ์๋ ์ ๋ํฌํ ๊ฐ๋ง ๋ฐํํ ๋ ์ด ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
IN ์ฐ์ฐ์์ ํน์ฑ์ IN(subquery), IN(์์๋ค) ํํ์ ์กฐ๊ฑด์ ๊ดํธ ์์ ์๋ ๊ฐ์ ๋ชฉ๋ก์์ ์ค๋ณต๋ ๊ฐ์ด ๋จผ์ ์ ๊ฑฐ๋ผ์ผ ํ๋ค.
์์ unique_subquery ์ ๊ทผ ๋ฐฉ๋ฒ์ IN(subquery) ์กฐ๊ฑด์ subquery ๊ฒฐ๊ณผ๊ฐ ์ค๋ณต๋ ๊ฐ์ ๋ง๋ค์ด๋ด์ง ์๋๋ค๋ ๋ณด์ฅ์ด ์์ผ๋ฏ๋ก ๋ณ๋์ ์ค๋ณต์ ์ ๊ฑฐํ ํ์๊ฐ ์์๋ค.
ํ์ง๋ง IN(subquery)์์ subquery๊ฐ ์ค๋ณต๋ ๊ฐ์ ๋ฐํํ ์๋ ์๋๋ฐ, ์ด ๋ ์ค๋ณต๋ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด์ ์ ๊ฑฐํ ์ ์์ ๋ index_subquery ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์ฌ์ฉ๋๋ค.
์ฆ
unique_subquery
์ ๊ทผ ๋ฐฉ๋ฒ์ IN(subquery) ์กฐ๊ฑด์์ ์๋ธ์ฟผ๋ฆฌ์ ๋ฐํ ๊ฐ์ด ์ ๋ํฌ ๊ฐ๋ค์ด๋ฏ๋ก ๋ณ๋์ ์ค๋ณต ์ ๊ฑฐ ์์
์ด ํ์ํ์ง ์๋ค๋ ์๋ฏธ์ด๊ณ
index_subqurey
์ ๊ทผ ๋ฐฉ๋ฒ์ IN(subquery) ์กฐ๊ฑด์์ ์๋ธ์ฟผ๋ฆฌ ๋ฐํ ๊ฐ์ด ์ค๋ณต๋ ๊ฐ์ด ์์ ์ ์์ง๋ง ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์ค๋ณต ๊ฐ์ ์ ๊ฑฐํ ์ ์๋ค๋ ์๋ฏธ์ด๋ค.
range๋ ๋ง๊ทธ๋๋ก ์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ
ํํ์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๋ค.
range๋ ์ธ๋ฑ์ค๋ฅผ ํ๋์ ๊ฐ์ด ์๋๋ผ ๋ฒ์๋ก ๊ฒ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํ๋๋ฐ, ์ฃผ๋ก "<, >, IS NULL, BETWEEN, IN, LIKE" ๋ฑ์ ์ฐ์ฐ์๋ฅผ ์ด์ฉํด ์ธ๋ฑ์ค๋ฅผ ๊ฒ์ํ ๋ ์ฌ์ฉ๋๋ค.
์ผ๋ง๋ ๋ง์ ๋ ์ฝ๋๋ฅผ ํ์๋ก ํ๋๋์ ๋ฐ๋ผ ์ฐจ์ด๋ ์๊ฒ ์ง๋ง range ์ ๊ทผ ๋ฐฉ๋ฒ๋ ์๋นํ ๋น ๋ฅด๋ฉฐ, ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ์ด ์ ๊ทผ ๋ฐฉ๋ฒ๋ง ์ฌ์ฉํด๋ ์ต์ ์ ์ฑ๋ฅ์ด ๋ณด์ฅ๋๋ค๊ณ ๋ณผ ์ ์๋ค.
mysql> explain
-> select * from employees where emp_no between 10002 and 10004;
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | employees | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 3 | 100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
๋ณดํต ์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ์ด๋ผ๊ณ ํ๋ฉด const
, ref
, range
์ธ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ๋ฒ์ ๋ชจ๋ ๋ฌถ์ด์ ์ง์นญํ๋ ๊ฒ์ด๋ผ๊ณ ์ดํดํ๊ณ
์
๋ฌด์ ๊ฐ๋ฐ์๋ DBA์ ์ํตํ ๋๋ const
, ref
, range
์ ๊ทผ ๋ฐฉ๋ฒ์ ๊ตฌ๋ถํด์ ์ธ๊ธํ๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์๋ค๊ณ ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ, ๋ ์ธ์ง ์ค์บ์ผ๋ก ์ธ๊ธํ ๋๊ฐ ๋ง์
"์ธ๋ฑ์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๋ค"๋ผ๋ ํํ์ ์ด ์ธ๊ฐ์ง ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ ๋๋ฅผ ์๋ฏธํ๋ค.
index_merge ์ ๊ทผ ๋ฐฉ๋ฒ์ 2๊ฐ ์ด์์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ๊ฐ๊ฐ์ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด๋ธ ํ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ณํฉํด์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ด๋ค.
๊ทธ๋ค์ง ํจ์จ์ ์ด์ง ์๋ค.
- ์ฌ๋ฌ ์ธ๋ฑ์ค๋ฅผ ์ฝ์ด์ผ ํ๋ฏ๋ก ์ผ๋ฐ์ ์ผ๋ก range ์ ๊ทผ ๋ฐฉ๋ฒ๋ณด๋ค ํจ์จ์ฑ์ด ๋จ์ด์ง
- ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ์์๋ index_merge๊ฐ ์ ์ฉ๋์ง ์์
- index_merge ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ ํญ์ 2๊ฐ ์ด์์ ์งํฉ์ด ๋๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ ์งํฉ์ ๊ต์งํฉ์ด๋ ํฉ์งํฉ, ๋๋ ์ค๋ณต ์ ๊ฑฐ์ ๊ฐ์ ๋ถ๊ฐ์ ์ธ ์์ ์ด ์ถ๊ฐ๋ก ์๊ตฌ๋๋ค
mysql> explain
-> select * from employees
-> where emp_no between 10001 and 11000 or first_name='Smith';
+----+-------------+-----------+-------------+----------------------+----------------------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | Extra |
+----+-------------+-----------+-------------+----------------------+----------------------+------------------------------------------------+
| 1 | SIMPLE | employees | index_merge | PRIMARY,ix_firstname | PRIMARY,ix_firstname | Using union(PRIMARY,ix_firstname); Using where |
+----+-------------+-----------+-------------+----------------------+----------------------+------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
์ ์ฟผ๋ฆฌ์์ or๋ก ์ฐ๊ฒฐ๋ ๋ ๊ฐ ์กฐ๊ฑด์ด ๋ชจ๋ ๊ฐ๊ฐ ๋ค๋ฅธ ์ธ๋ฑ์ค๋ฅผ ์ต์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ์กฐ๊ฑด์ด๋ค.
๋ฐ๋ผ์ ์ตํฐ๋ง์ด์ ๋ between ์กฐ๊ฑด์ employees ํ
์ด๋ธ์ pk๋ฅผ ์ด์ฉํด ์กฐํํ๊ณ , name ์กฐ๊ฑด์ ix_firstname ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์กฐํํ ํ ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณํฉํ๋ ํํ๋ก ์ฒ๋ฆฌํ๋ ์คํ ๊ฒํ์ ๋ง๋ค์ด๋ธ๋ค.
index ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ธ๋ฑ์ค๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ์ฝ๋ ์ธ๋ฑ์ค ํ ์ค์บ
์ ์๋ฏธํ๋ค.
์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ๊ธฐ๋ ํ์ง๋ง range ์ฒ๋ผ ์ธ๋ฑ์ค์ ํ์ํ ๋ถ๋ถ๋ง ์ฝ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ํจ์จ์ ์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๋ณด๊ธฐ๋ ์ด๋ ต๋ค.
๋ค๋ง ํ ํ
์ด๋ธ ์ค์บ
๋ฐฉ์๊ณผ ๋น๊ตํ์ ๋ ๋น๊ตํ๋ ๋ ์ฝ๋ ๊ฑด์๋ ๊ฐ์๋ ์ธ๋ฑ์ค๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ ์ ์ฒด ํ์ผ๋ณด๋ค ํฌ๊ธฐ๊ฐ ์์ผ๋ฏ๋ก ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋ฉฐ
์ฟผ๋ฆฌ์ ๋ด์ฉ์ ๋ฐ๋ผ ์ ๋ ฌ๋ ์ธ๋ฑ์ค์ ์ฅ์ ์ ์ด์ฉํ ์ ์๋ค๋ ์ ์์ ํจ์ฌ ํจ์จ์ ์ด๋ผ ํ ์ ์๋ค.
๋ค์ ์ธ๊ฐ์ง ์กฐ๊ฑด ๊ฐ์ด๋ฐ (1, 2) ์กฐ๊ฑด์ ์ถฉ์กฑํ๊ฑฐ๋ (1, 3) ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ์ฟผ๋ฆฌ์์ ์ฌ์ฉ๋๋ ์ฝ๊ธฐ ๋ฐฉ์์ด๋ค.
- range๋ const, ref ๊ฐ์ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ
- ์ธ๋ฑ์ค์ ํฌํจ๋ ์นผ๋ผ๋ง์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ์ฟผ๋ฆฌ์ธ ๊ฒฝ์ฐ
- ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์ ๋ ฌ์ด๋ ๊ทธ๋ฃจํ ์์ ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ(๋ณ๋์ ์ ๋ ฌ ์์ ์ ํผํ ์ ์๋ ๊ฒฝ์ฐ)
mysql> explain
-> select * from departments order by dept_name desc limit 10;
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+----------------+
| 1 | SIMPLE | departments | NULL | ALL | NULL | NULL | NULL | NULL | 9 | 100.00 | Using filesort |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
์ ์คํ ๊ณํ์ ํ
์ด๋ธ์ ์ธ๋ฑ์ค๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ์ฝ๋ index ์ ๊ทผ ๋ฐฉ๋ฒ์ด์ง๋ง limit ์กฐ๊ฑด์ด ์๊ธฐ ๋๋ฌธ์ ์๋นํ ํจ์จ์ ์ด๋ค. ๋จ์ํ ์ธ๋ฑ์ค๋ฅผ ์ญ์์ผ๋ก ์ฝ์ด 10๊ฐ๋ง ๊ฐ์ ธ์ค๋ฉด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง limit ์กฐ๊ฑด์ด ์๊ฑฐ๋ ๊ฐ์ ธ์์ผ ํ ๋ ์ฝ๋ ๊ฑด์๊ฐ ๋ง์์ง๋ฉด ์๋นํ ๋๋ฆฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ค.
all์ ํ ํ
์ด๋ธ ์ค์บ
์ ์๋ฏธํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๋ค. ํ
์ด๋ธ์ ์ฒ์๋ถํฐ ๋๊น์ง ์ ๋ถ ์ฝ์ด์ ๋ถํ์ํ ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐ(์ฒดํฌ ์กฐ๊ฑด์ด ์กด์ฌํ๋ค๋ฉด)ํ๊ณ ๋ฐํํ๋ค.
ํ ํ
์ด๋ธ ์ค์บ์ ์ง๊ธ๊น์ง ์ค๋ช
ํ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก๋ ์ฒ๋ฆฌํ ์ ์์ ๋ ๊ฐ์ฅ ๋ง์ง๋ง์ ์ ํํ๋ ๊ฐ์ฅ ๋นํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ด๋ค.
๋ค๋ฅธ DBMS์ ๋ง์ฐฌ๊ฐ์ง๋ก InnoDB๋ ํ ํ
์ด๋ธ ์ค์บ์ด๋ ์ธ๋ฑ์ค ํ ์ค์บ๊ณผ ๊ฐ์ ๋๋์ ๋์คํฌ I/O๋ฅผ ์ ๋ฐํ๋ ์์
์ ์ํด ํ๊บผ๋ฒ์ ๋ง์ ํ์ด์ง๋ฅผ ์ฝ์ด ๋ค์ด๋ ๋ฆฌ๋ ์ดํค๋(Read Ahead)
๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๋ฐ์ดํฐ ์จ์ดํ์ฐ์ค๋ ๋ฐฐ์น ํ๋ก๊ทธ๋จ์ฒ๋ผ ๋์ฉ๋์ ๋ ์ฝ๋๋ฅผ ์ฒ๋ฆฌํ๋ ์ฟผ๋ฆฌ์์๋ ์๋ชป ํ๋๋ ์ฟผ๋ฆฌ(์ต์ง๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๊ฒ ํ๋๋ ์ฟผ๋ฆฌ)๋ณด๋ค ๋ ๋์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด๊ธฐ๋ ํ๋ค.
์ฟผ๋ฆฌ๋ฅผ ํ๋ํ๋ ๊ฒ์ด ๋ฌด์กฐ๊ฑด ์ธ๋ฑ์ค ํ ์ค์บ์ด๋ ํ ์ด๋ธ ํ ์ค์บ์ ์ฌ์ฉํ์ง ๋ชปํ๊ฒ ํ๋ ๊ฒ์ ์๋๋ผ๋ ์ ์ ๊ธฐ์ตํด์ผํ๋ค.
์ผ๋ฐ์ ์ผ๋ก index์ all ์ ๊ทผ ๋ฐฉ๋ฒ์ ์์ ๋ฒ์๋ฅผ ์ ํํ๋ ์กฐ๊ฑด์ด ์๋๋ฏ๋ก ๋น ๋ฅธ ์๋ต์ ์ฌ์ฉ์์๊ฒ ๋ณด๋ด์ผ ํ๋ ์น ์๋น์ค ๋ฑ๊ณผ ๊ฐ์ ์จ๋ผ์ธ ํธ๋์ญ์ ์ฒ๋ฆฌ ํ๊ฒฝ์๋ ์ ํฉํ์ง ์๋ค. ํ ์ด๋ธ์ด ๋งค์ฐ ์์ง ์๋ค๋ฉด ์ค์ ๋ก ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ ์ ๋ ์ ์ฅํ ์ํ์์ ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ ํ์ธํด๋ณด๊ณ ์ ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
์ ๊ธ์ ์ฑ RealMySQL 8.0์ ๊ตฌ์ ํ์ฌ ์ฝ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.