๐ฏ MySQL EXPLAIN ์คํ๊ณํ ๋ง์คํฐํ๊ธฐ(feat. RealMySQL 8.0)
์คํ ๊ณํ(EXPLAIN) ์ด๋?
๋๋ถ๋ถ์ DBMS๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ณ , ๋น ๋ฅด๊ฒ ์ ์ฅ ๋ฐ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ฃผ๋ชฉ์ ์ด๋ค.
์ด๋ฌํ ๋ชฉ์ ์ ๋ฌ์ฑํ๊ธฐ ์ํด ์ฌ์ฉ์์ ์ฟผ๋ฆฌ๋ฅผ ์ตํฐ๋ง์ด์ ๊ฐ ์ต์ ์ผ๋ก ์ฒ๋ฆฌ๋ ์ ์๋๋ก ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์ ์๋ฆฝํ ์ ์์ด์ผ ํ๋ค.
ํ์ง๋ง ์ตํฐ๋ง์ด์ ๊ฐ ํญ์ ์ต์ ์ ์คํ ๊ณํ์ ๋ง๋ค์ด๋ผ ์ ์๋ ๊ฒ์ ์๋๋ฏ๋ก DBMS ์๋ฒ๋ ์ด๋ฌํ ๋ฌธ์ ์ ์ ๊ด๋ฆฌ์๋ ์ฌ์ฉ์๊ฐ ๋ณด์ํ ์ ์๋๋ก EXPLAIN ๋ช ๋ น์ผ๋ก ์ตํฐ๋ง์ด์ ๊ฐ ์๋ฆฝํ ์คํ ๊ณํ์ ํ์ธํ ์ ์๋ค.
ํ ์คํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค: https://github.com/datacharmer/test_db
์คํ ๊ณํ | ์๋ฏธ |
id | SELECT ์ฟผ๋ฆฌ ๋ณ ๋ถ์ฌ๋๋ ์๋ณ์ ๊ฐ |
select_type | ๊ฐ ๋จ์ SELECT ์ฟผ๋ฆฌ๊ฐ ์ด๋ค ํ์ ์ ์ฟผ๋ฆฌ์ธ์ง ํ์๋๋ ์นผ๋ผ |
table | ์ ๊ทผํ๊ณ ์๋ ํ ์ด๋ธ์ ๋ํ ํ์ |
partitions | ํ ์ด๋ธ์ ํํฐ์ ๋์ด ๋์ด ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ๋๋ ํ๋ |
type | ๊ฐ ํ ์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์ฝ์๋์ง์ ๋ํ ์ ๊ทผ ๋ฐฉ์ |
possible_keys | “์ฌ์ฉ๋ ๋ฒํ๋ ์ธ๋ฑ์ค์ ๋ชฉ๋ก”์ด๋ฉฐ ๋ฐ๋์ ์ฌ์ฉ๋ ๊ฒ์ ์๋ |
key | ์ต์ข ์ ํ๋ ์คํ ๊ณํ์์ ์ฌ์ฉ๋๋ ์ธ๋ฑ์ค |
key_len | ์ ํ๋ ์ธ๋ฑ์ค์ ๊ธธ์ด๋ฅผ ์๋ฏธ |
ref | ์ ๊ทผ ๋ฐฉ๋ฒ์ด ref๋ฉด ์ฐธ์กฐ ์กฐ๊ฑด(equal ๋น๊ต ์กฐ๊ฑด)์ผ๋ก ์ด๋ค ๊ฐ์ด ์ ๊ณต๋๋์ง ํ์ |
rows | ์คํ ๊ณํ์ ํจ์จ์ฑ ํ๋จ์ ์ํด ์์ธกํ๋ ๋ ์ฝ๋ ๊ฑด์๋ฅผ ๋ณด์ฌ์ค๋ค. (์ ํํ์ง๋ ์์) |
filtered | ํํฐ๋ง๋๊ณ ๋จ์ ๋ ์ฝ๋์ ๋น์จ (์ ํํ์ง๋ ์์) |
Extra | ์ตํฐ๋ง์ด์ ๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง์ ๋ํด ์๋ ค์ฃผ๋ ํํธ ๊ฐ |
์คํ ๊ณํ ๋ถ์
EXPLAIN ๋ช ๋ น์ผ๋ก MySQL์์ ์คํ ๊ณํ์ ํ์ธํ ์ ์๋๋ฐ ์ด๋ ์ฟผ๋ฆฌ ๋ฌธ์ฅ์์ ์ฌ์ฉ๋ ํ ์ด๋ธ์ ๊ฐฏ์๋งํผ ์ถ๋ ฅํ๋ค.
๐ 1. id
- SELECT ์ฟผ๋ฆฌ ๋ณ ๋ถ์ฌ๋๋ ์๋ณ์ ๊ฐ
๐ 2. select_type
- ๊ฐ ๋จ์ SELECT ์ฟผ๋ฆฌ๊ฐ ์ด๋ค ํ์ ์ ์ฟผ๋ฆฌ์ธ์ง ํ์๋๋ ์นผ๋ผ
2.1 SIMPLE
- ๋จ์ SELECT ์ฟผ๋ฆฌ
- ์ฟผ๋ฆฌ ๋ฌธ์ฅ์ด ์๋ฌด๋ฆฌ ๋ณต์กํ๋๋ผ๋ ์คํ ๊ณํ์์ select_type์ด SIMPLE์ธ ๋จ์ ์ฟผ๋ฆฌ๋ ์ต๋ ํ๋๋ง ์กด์ฌ
2.2 PRIMARY
- UNION์ด๋ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ง๋ SELECT ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์์ ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ์ ์๋ ๋จ์ ์ฟผ๋ฆฌ
- SIMPLE์ ๋ง์ฐฌ๊ฐ์ง ์ต๋ ํ๋๋ง ์กด์ฌ
2.3 UNION
- UNION์ผ๋ก ๊ฒฐํฉํ๋ ๋จ์ SELECT ์ฟผ๋ฆฌ ๊ฐ์ด๋ฐ ์ฒซ ๋ฒ์งธ๋ฅผ ์ ์ธํ ๋ ๋ฒ์งธ ์ดํ ์ฟผ๋ฆฌ๋ค
- UNION์ ์ฒซ ๋ฒ์งธ ๋จ์ SELECT๋ UNION๋๋ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ค์ ๋ชจ์์ ์ ์ฅํ๋ ์์ ํ ์ด๋ธ(DERIVED)
๐ก Quiz 1. ์ ์ฟผ๋ฆฌ์์ DERIVED ํ์ ๊ณผ UNION ํ์ ์ ๊ฐ๊ฐ ์ด๋ค ์ฟผ๋ฆฌ๋ค์ผ๊น?
-- 1. DERIVED
-- 2. UNION
-- 3. UNION
- <>๋ก ๋๋ฌ์ธ์ธ ์ด๋ฆ์ด ๋ช
์๋๋ ๊ฒฝ์ฐ ์์ ํ
์ด๋ธ์ ์๋ฏธํจ
- <derived2> → id ๊ฐ์ด 2์ธ ์คํ ๊ณํ์ผ๋ก๋ถํฐ ๋ง๋ค์ด์ง ํ์(DERIVED) ํ ์ด๋ธ
2.4 DEPENDENT UNION
- DEPENDENT๋ UNION์ด๋ UNION ALL๋ก ๊ฒฐํฉ๋ ๋จ์ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ถ ์ฟผ๋ฆฌ์ ์ํด ์ํฅ์ ๋ฐ๋ ๊ฒ
- ์๋ ์ฟผ๋ฆฌ์์ ์ตํฐ๋ง์ด์ ๋ IN ๋ด๋ถ์ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํ์ง ์๊ณ , ์ธ๋ถ์ employees ํ ์ด๋ธ์ ๋จผ์ ์ฝ์ ํ ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์คํ
- ์ด๋ employees ํ ์ด๋ธ์ ์นผ๋ผ๊ฐ์ด ์๋ธ์ฟผ๋ฆฌ์ ์ํฅ์ ์ค
- (๋ด๋ถ ์ฟผ๋ฆฌ๊ฐ ์ธ๋ถ์ ๊ฐ์ ์ฐธ์กฐํด์ ์ฒ๋ฆฌ๋ ๋)
2.5 UNION RESULT
- UNION RESULT๋ UNION ๊ฒฐ๊ณผ๋ฅผ ๋ด์๋๋ ํ ์ด๋ธ
- <union2,3> : id ๊ฐ์ด 2, 3 ์ฟผ๋ฆฌ์ ์กฐํ ๊ฒฐ๊ณผ๋ฅผ UNION
2.6 SUBQUERY
- select_type์ SUBQUERY๋ FROM ์ ์ด์ธ์์ ์ฌ์ฉ๋๋ ์๋ธ์ฟผ๋ฆฌ๋ง์ ์๋ฏธํจ
๐ก Quiz 2. ์๋ธ์ฟผ๋ฆฌ์ ์ข ๋ฅ๋ ์ด๋ ํ ๊ฒ๋ค์ด ์์๊น? (Hint: SELECT, FROM, WHERE ์ )
- SELECT: ์ค์นผ๋ผ ์๋ธ์ฟผ๋ฆฌ
- FROM: ์ธ๋ผ์ธ ๋ทฐ
- WHERE: ์ค์ฒฉ ์๋ธ์ฟผ๋ฆฌ
2.8 DERIVED
- DERIVED๋ ๋จ์ SELECT ์ฟผ๋ฆฌ์ ์คํ ๊ฒฐ๊ณผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ ๋์คํฌ์ ์์ ํ ์ด๋ธ์ ์์ฑํ๋ ๊ฒ
- select_type์ด DERIVED์ธ ๊ฒฝ์ฐ์ ์์ฑ๋๋ ์์ ํ ์ด๋ธ์ ํ์ ํ ์ด๋ธ์ด๋ผ๊ณ ๋ ํจ
- MySQL 5.6 ๋ฒ์ ๋ถํฐ๋ ์ตํฐ๋ง์ด์ ์ต์ ์ ๋ฐ๋ผ ์ด์ ๋ฒ์ ๊ณผ๋ ๋ฌ๋ฆฌ ์์ ํ ์ด๋ธ์๋ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํด์ ๋ง๋ค ์ ์๊ฒ ์ต์ ํ๋จ
- MySQL ์๋ฒ๋ ๋ฒ์ ์ด ์ ๊ทธ๋ ์ด๋๋๋ฉด์ ์กฐ์ธ ์ฟผ๋ฆฌ์ ๋ํ ์ต์ ํ๋ ๋ง์ด ์ฑ์๋ ์ํ
- ํ์ ํ
์ด๋ธ(DERIVED)์ ๋ํ ์ต์ ํ๊ฐ ๋ถ์กฑํ ๋ฒ์ ์ MySQL ์๋ฒ๋ฅผ ์ฌ์ฉ ์ค์ผ ๊ฒฝ์ฐ(MySQL 5.x ๋ฒ์ ), ๊ฐ๋ฅํ๋ค๋ฉด DERIVED ํํ์ ์คํ ๊ณํ์ ์กฐ์ธ์ผ๋ก ํด๊ฒฐํ ์ ์๊ฒ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด ์ข๋ค.
- ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์คํ ๊ณํ์ ํ์ธํด๋ณด๊ณ ๊ฒฐ์ ํ๋ ๊ฒ
๐ก ํ์ค ์์ฝ: ์๋ธ์ฟผ๋ฆฌ ๋์ ์กฐ์ธ์ ์ฌ์ฉํ์
์ฟผ๋ฆฌ๋ฅผ ํ๋ํ๊ธฐ ์ํด ์คํ ๊ณํ์ ํ์ธํ ๋ ๊ฐ์ฅ ๋จผ์ select_type ์ปฌ๋ผ์ ๊ฐ์ด DERIVED์ธ ๊ฒ์ด ์๋์ง ํ์ธํ๊ณ , ์๋ธ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ธ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค๋ ์กฐ์ธ์ ์ฌ์ฉํ ๊ฒ์ ๊ฐ๋ ฅํ ๊ถ์ฅํ๋ค. -Real MySQL 8.0 -
2.12 MATERIALIZED
- MySQL 5.6 ๋ฒ์ ๋ถํฐ ๋์ ๋ select_type์ผ๋ก ์ฃผ๋ก FROM์ , In(Subquery) ํํ์ ์ฟผ๋ฆฌ์์ ํฌํจ๋์ด ์๋ ์๋ธ์ฟผ๋ฆฌ์ ์ต์ ํ๋ฅผ ์ํด ์ฌ์ฉ
- MySQL 5.6 ๋ฒ์ ๊น์ง๋ employees ํ ์ด๋ธ์ ์ฝ์ด์ employees ํ ์ด๋ธ์ ๋ ์ฝ๋๋ง๋ค salaries ํ ์ด๋ธ์ ์ฝ๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ํํ๋ก ์ฒ๋ฆฌ๋๋ค. (Table Full Scan)
- MySQL 5.7 ๋ฒ์ ๋ถํฐ ์๋ธ์ฟผ๋ฆฌ์ ๋ด์ฉ์ ์์ ํ ์ด๋ธ๋ก ๊ตฌ์ฒดํ(Materialization) ํ ํ ์์ ํ ์ด๋ธ ์ฌ์ฉ
- MySQL 5.6 Switchable Optimizations(semijoin=on)
(์ ์ต์ ํ๊ฐ ์ด๋์ ๋์ ์ฐจ์ด๊ฐ ๋ฐ์ํ๋ ์ง๋ ์๋ *5.7์ ์์ ์ฐธ๊ณ )
๐ 3. table
- ์ ๊ทผํ๊ณ ์๋ ํ ์ด๋ธ์ ๋ํ ํ์
- MySQL ์๋ฒ์ ์คํ ๊ณํ์ ๋จ์ SELECT ์ฟผ๋ฆฌ ๊ธฐ์ค์ด ์๋ ํ ์ด๋ธ ๊ธฐ์ค์ผ๋ก ํ์๋๋ค.
- ํ ์ด๋ธ์ ์ด๋ฆ์ ๋ณ์นญ์ด ๋ถ์ฌ๋ ๊ฒฝ์ฐ์๋ ๋ณ์นญ ํ์
๐ก Quiz 3. ์คํ ๊ณํ์ ํตํด ์ฟผ๋ฆฌ๋ฅผ ์ ์ถํด๋ณด์.
- ์ฒซ ๋ฒ์งธ ๋ผ์ธ์ <derived2>๋ฅผ ํตํด id = 2์ธ ๋ผ์ธ์ด ๋จผ์ ์คํ๋๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํ์ ํ ์ด๋ธ๋ก ์ค๋น
- ์ธ ๋ฒ์งธ ๋ผ์ธ(id = 2)์ ๋ณด๋ฉด select_type = DERIVED, table = s ์ด๋ฏ๋ก salaries(๋ณ์นญ: s) ํ
์ด๋ธ์ ์ฝ์ด์ ํ์ ํ
์ด๋ธ ์์ฑ
- SELECT ~ FROM salaries s
- ์ฒซ ๋ฒ์งธ ๋ผ์ธ๊ณผ ๋ ๋ฒ์งธ ๋ผ์ธ์ ๊ฐ์ id ๊ฐ์ ๊ฐ์ง๊ณ ์๋๊ฒ์ผ๋ก ๋ณด์ 2๊ฐ ํ
์ด๋ธ์ด ์กฐ์ธ๋ ์ฟผ๋ฆฌ(e, s ํ
์ด๋ธ)์ธ ๊ฑธ ์ ์ ์์
- FROM employees e JOIN SELECT ~ FROM salaries s ON ~
- <derived 2> ํ
์ด๋ธ์ด e ํ
์ด๋ธ๋ณด๋ค ๋จผ์ (์์) ํ์๋๊ธฐ ๋๋ฌธ์ <derived 2>๊ฐ ๋๋ผ์ด๋น ํ
์ด๋ธ์ด ๋๊ณ e ํ
์ด๋ธ์ด ๋๋ฆฌ๋ธ ํ
์ด๋ธ์ด ๋๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
- ๋ณดํต ์ตํฐ๋ง์ด์ ๋ ํ ์ด๋ธ ์กฐ์ธ ์ ๋ ์ฝ๋๊ฐ ์ ์ ํ ์ด๋ธ์ ๋จผ์ ์ฝ์(๋๋ผ์ด๋น ํ ์ด๋ธ)
*์ ์คํ ๊ณํ์ ํตํด ์๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ๊ฒ์ ์ ์ถํ ์ ์๋ค.
๐ 4. partitions
- ํ
์ด๋ธ์ ํํฐ์
๋์ด ๋์ด ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ๋๋ ํ๋
- ์ฝ๊ฒ ๋งํ๋ฉด ๋์ผํ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ๋ถํ ํ์ฌ ์ ์ฅํ๋ ๋ฐฉ์
- ~ MySQL 5.7 ๋ฒ์ : EXPLAIN PARTITION
- MySQL 8.0 ๋ฒ์ ๋ถํฐ๋ EXPLAIN ๋ช ๋ น์ผ๋ก ํํฐ์ ๊ด๋ จ ์คํ ๊ณํ๊น์ง ํ์ธ ๊ฐ๋ฅ
- ์ตํฐ๋ง์ด์ ๋ ์ฟผ๋ฆฌ์ hire_date ์นผ๋ผ ์กฐ๊ฑด์ ๋ณด๊ณ , ์ฟผ๋ฆฌ์์ ํ์ํ ๋ฐ์ดํฐ๋ p2015, p2020 ํํฐ์ ์๋ง ์๋ค๋ ๊ฒ์ ํ์ → ํด๋น ํํฐ์ ๋ง ์ค์บ
- ํํฐ์ ํ๋ฃจ๋ : ์ฟผ๋ฆฌ ์ํ์ ์ํด ์ ๊ทผํด์ผ ํ ํ ์ด๋ธ๋ง ๊ณจ๋ผ๋ด๋ ๊ณผ์
- type์ ๋ณด๋ฉด ALL์ด๋ผ ํ ํ ์ด๋ธ ์ค์บ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๋๋๋ฐ, MySQL ํฌํจ ๋๋ถ๋ถ RDBMS์์ ์ง์ํ๋ ํํฐ์ ์ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๊ฐ๋ณ ํ ์ด๋ธ์ฒ๋ผ ๋ณ๋์ ์ ์ฅ ๊ณต๊ฐ์ ๊ฐ์ง๊ธฐ ๋๋ฌธ
- ์ ์ฟผ๋ฆฌ๋ employees_partitions ํ ์ด๋ธ์ ํน์ ํํฐ์ (p2015, p2020)๋ง ํ ์ค์บ์ ์คํ
- ํํฐ์ ๋ → ์ํ / ์์ง
๐ 5. type
- ๊ฐ ํ
์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์ฝ์๋์ง์ ๋ํ ์ ๊ทผ ๋ฐฉ์
- ๋ฐฉ์ → ์ธ๋ฑ์ค, ํ ํ ์ด๋ธ ์ค์บ, ์ธ๋ฑ์ค ํ ์ค์บ ๋ฑ๋ฑ
- ์ฟผ๋ฆฌ ํ๋ ์ ๋ฐ๋์ ์ฒดํฌํด์ผ ํ ์ค์ํ ์ ๋ณด
- type ์นผ๋ผ์ ํ์๋ ์ ์๋ ๊ฐ๋ค .. (12๊ฐ)
- system, const, eq_ref, ref, fulltext, ref_or_null, unique_subquery, index_subquery, range, index_merge, index, ALL
- ALL(ํ ์ด๋ธ ํ ์ค์บ)์ ์ ์ธํ ๋๋จธ์ง๋ ๋ชจ๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ์
- system → ALL ๊ฐ์๋ก ์ฑ๋ฅ์ด ๋๋ ค์ง
- MySQL ์ตํฐ๋ง์ด์ ๋ ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ๋ฒ๊ณผ ๋น์ฉ์ ํจ๊ป ๊ณ์ฐํด์ ์ต์์ ๋น์ฉ์ด ํ์ํ ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ ํํด ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํจ
5.1 system
- ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์ต๋ 1๊ฑด ์กด์ฌํ๋ ํ ์ด๋ธ์ ์ฐธ์กฐํ๋ ํํ์ ์ ๊ทผ ๋ฐฉ๋ฒ
- InnoDB ์คํ ๋ฆฌ์ง ์์ง์์๋ ๋ํ๋์ง ์๊ณ , MyISAM/MEMORY ํ ์ด๋ธ์์๋ง ์ฌ์ฉ๋๋ ์ ๊ทผ ๋ฐฉ์
- ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ 1๊ฑด ์ดํ์ธ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ ์ ์๊ธฐ์ ๊ฑฐ์ ๋ณด์ด์ง ์์
5.2 const
- ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋์ 1๊ฑด์ ๋ฐํํ๋ ์ฟผ๋ฆฌ์ ์ฒ๋ฆฌ ๋ฐฉ์
- PK ๋ฐ Unique Key ์ปฌ๋ผ์ ์ด์ฉํ๋ ์กฐ๊ฑด์
- ์๋ ์ฒ๋ผ ๋ค์ค ์นผ๋ผ์ผ๋ก ๊ตฌ์ฑ๋ PK์์ ์ผ๋ถ ์นผ๋ผ๋ง ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉํ ๋๋ const ์ ๊ทผ ๋ฐฉ์ ๋ถ๊ฐ๋ฅ
- ์ค์ ๋ ์ฝ๋๊ฐ 1๊ฑด๋ง ์ ์ฅ๋์ด ์๋๋ผ๋ MySQL ์์ง์ด ํ ์ด๋ธ์ ์ฝ๊ธฐ ์ ์๋ ๋ ์ฝ๋๊ฐ 1๊ฑด์ด๋ผ๋ ๊ฒ์ ํ์ ํ ์ ์๊ธฐ ๋๋ฌธ
- PK์ ์ผ๋ถ๋ง ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉํ ๋๋ type ์นผ๋ผ์ ref๋ก ํ์
PK์ ๋ชจ๋ ์นผ๋ผ์ ๋๋ฑ ์กฐ๊ฑด์ผ๋ก WHERE ์ ์ ๋ช ์ํ๋ฉด const ์ ๊ทผ ๋ฐฉ์ ์ฌ์ฉ
5.3 eq_ref
- ์ฌ๋ฌ ํ ์ด๋ธ์ด ์กฐ์ธ๋๋ ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์์๋ง ํ์
- ์กฐ์ธ์์ ์ฒ์ ์ฝ์ ํ ์ด๋ธ์ ์นผ๋ผ๊ฐ์, ๋ค์ ์ฝ์ ํ ์ด๋ธ์ PK๋ ์ ๋ํฌ ํค ์นผ๋ผ์ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ์ฉํ ๋ eq_ref ์ ๊ทผ๋ฐฉ์ ์ฌ์ฉ
- ๋ ๋ฒ์งธ ์ดํ์ ์ฝ๋ ํ ์ด๋ธ์ type ์นผ๋ผ์ eq_ref๊ฐ ํ์
- ์กฐ์ธ์์ ๋ ๋ฒ์งธ ์ดํ์ ์ฝ๋ ํ ์ด๋ธ์์ ๋ฐ๋์ 1๊ฑด๋ง ์กด์ฌํ๋ค๋ ๋ณด์ฅ์ด ์์ด์ผ ์ฌ์ฉ
5.4 ref
- ์กฐ์ธ์ ์์์ ๊ด๊ณ์์ด ๋๋ฑ(Equal) ์กฐ๊ฑด์ผ๋ก ๊ฒ์ํ ๋ ์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ์
- ref ํ์ ์ ๋ฐํ๋๋ ๋ ์ฝ๋๊ฐ ๋ฐ๋์ 1๊ฑด์ด๋ผ๋ ๋ณด์ฅ์ด ์์ผ๋ฏ๋ก const, eq_ref ๋ณด๋ค๋ ๋๋ฆฌ์ง๋ง ๋๋ฑํ ์กฐ๊ฑด์ผ๋ก๋ง ๋น๊ต๋๊ธฐ์ ๋งค์ฐ ๋น ๋ฅธ ๋ ์ฝ๋ ์กฐํ ๋ฐฉ๋ฒ ์ค ํ๋
๐ก const, ref ์ ๋ฆฌ
- const: ๋ชจ๋ ์ปฌ๋ผ์ ๋ํด PK, ์ ๋ํฌ ํค ๋ฑ ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์(๋ฐ๋์ 1๊ฑด์ ๋ ์ฝ๋๋ง ๋ฐํ)
- ref: ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์(1๊ฑด์ ๋ ์ฝ๋๋ง ๋ฐํ๋๋ค๋ ๋ณด์ฅ์ด ์์ด๋ ๋จ)
- const, eq_ref, ref์ ์ข์ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ํฌ๊ฒ ์ ๊ฒฝ์ฐ์ง ์๊ณ ๋์ด๊ฐ๋ ๋ฌด๋ฐฉ
5.5 fulltext
- fulltext ์ ๊ทผ ๋ฐฉ๋ฒ์ MySQL ์๋ฒ์ ์ ๋ฌธ ๊ฒ์(Full-text Search) ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด ๋ ์ฝ๋ ์ ๊ทผ
- ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค๋ ์ ํ ๋ค๋ฅธ SQL ๋ฌธ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค
- MATCH (…) AGAINST (…) ๊ตฌ๋ฌธ??
5.6 ref_or_null
- ref์์ NULL ๋น๊ต๋ง ์ถ๊ฐ๋ ํํ
- ๋ง์ด ํ์ฉ๋์ง๋ ์์ผ๋ ์ฌ์ฉ๋๋ค๋ฉด ๋์์ง ์์ ์ ๋์ ์ ๊ทผ ๋ฐฉ๋ฒ ์ ๋๋ก ๊ธฐ์ต
5.7 unique_subquery
- WHERE ์กฐ๊ฑด์ ์์ ์ฌ์ฉ๋ ์ ์๋ IN(Subquery) ํํ์ ์ฟผ๋ฆฌ๋ฅผ ์ํ ์ ๊ทผ ๋ฐฉ๋ฒ
- ์ด๋ฆ ๊ทธ๋๋ก ์๋ธ์ฟผ๋ฆฌ์์ ์ค๋ณต๋์ง ์๋ ์ ๋ํฌํ ๊ฐ๋ง ๋ฐํํ ๋ ์ฌ์ฉ
๐ก type์ด unique_subquery์ด ์๋๋ฐ์??
MySQL 8.0 ๋ฒ์ ์์๋ ์ ์ฟผ๋ฆฌ์ฒ๋ผ WHERE ์กฐ๊ฑด์ ์ ์ฌ์ฉ๋ IN(Subquery) ํํ์ ์ธ๋ฏธ ์กฐ์ธ์ ์ต์ ํํ๊ธฐ ์ํด ๋ง์ ๊ธฐ๋ฅ์ด ๋์ ๋์๊ณ , ์ด๋ก ์ธํด ์ต์ ํ๋ ์คํ ๊ณํ์ด ๋ณด์ด๋ ๊ฒ semijoin ์ต์ ํ ์ต์ ์ on/off ํ๋ฉด ์คํ ๊ณํ์ด ๋ค๋ฅด๊ฒ ๋ณด์
***
MySQL 5.6 ๋ฒ์ ๊น์ง๋ employees ํ ์ด๋ธ์ ์ฝ์ด์ employees ํ ์ด๋ธ์ ๋ ์ฝ๋๋ง๋ค salaries ํ ์ด๋ธ์ ์ฝ๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ํํ๋ก ์ฒ๋ฆฌ๋๋ค.
์ 2.12 MATERIALIZED ์์ ์ธ๊ธํ์๋ ์๋ธ์ฟผ๋ฆฌ ์ต์ ํ์ ์ฐจ์ด์ ์ semijoin=on/off๋ฅผ ํตํด ์๋ ์ฌ์ง์ ํตํด ํ์ ํด๋ณด์.
- MySQL 5.6 ๋ฒ์ ๊น์ง๋ employees ํ ์ด๋ธ์ ์ฝ์ด์ employees ํ ์ด๋ธ์ ๋ ์ฝ๋๋ง๋ค salaries ํ ์ด๋ธ์ ์ฝ๋ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ํํ๋ก ์ฒ๋ฆฌ๋๋ค. (Table Full Scan)
- MySQL 5.7 ๋ฒ์ ๋ถํฐ ์๋ธ์ฟผ๋ฆฌ์ ๋ด์ฉ์ ์์ ํ ์ด๋ธ๋ก ๊ตฌ์ฒดํ(Materialization) ํ ํ ์์ ํ ์ด๋ธ ์ฌ์ฉ
5.8 index_subquery
- IN(subquery)์์ ์๋ธ์ฟผ๋ฆฌ๊ฐ ์ค๋ณต๋ ๊ฐ์ ๋ฐํํ ์ ์๋๋ฐ, ์ด๋ ์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์ ์ค๋ณต๋ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด์ ์ ๊ฑฐํ ์ ์์ ๋ index_subquery ์ ๊ทผ ๋ฐฉ๋ฒ ์ฌ์ฉ
- unqiue_subquery: ์๋ธ์ฟผ๋ฆฌ ๋ฐํ ๊ฐ์ ์ค๋ณต X
- index_subquery: ์๋ธ์ฟผ๋ฆฌ ๋ฐํ ๊ฐ์ ์ค๋ณต์ด ์์ ์ ์์ผ๋ index๋ฅผ ์ด์ฉํด ์ค๋ณต ์ ๊ฑฐ
5.9 range
- ์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ ํํ์ ์ ๊ทผ ๋ฐฉ๋ฒ
- range๋ ์ธ๋ฑ์ค๋ฅผ ํ๋์ ๊ฐ์ด ์๋ ๋ฒ์๋ก ๊ฒ์ํ๋ ๊ฒฝ์ฐ
- ์ฃผ๋ก “<, >, IS NULL, BETWEEN, IN, LIKE” ๋ฑ์ ์ฐ์ฐ์๋ฅผ ์ด์ฉํด ์ธ๋ฑ์ค ๊ฒ์ํ ๋ ์ฌ์ฉ
- ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฟผ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ
- ์์์ ์๊ฐํ type ์นผ๋ผ์์ ์ฐ์ ์์(์ฑ๋ฅ)๊ฐ ๋ฎ์ผ๋ range ์ ๊ทผ ๋ฐฉ๋ฒ๋ ์๋นํ ๋น ๋ฆ
- ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ ์ด ์ ๊ทผ ๋ฐฉ๋ฒ๋ง ์ฌ์ฉํด๋ ์ต์ ์ ์ฑ๋ฅ์ด ๋ณด์ฅ๋๋ค๊ณ ๋ณผ ์ ์์
5.11 index
- index ์ ๊ทผ ๋ฐฉ๋ฒ์ ๋ง์ ์ฌ๋์ด ์์ฃผ ์คํดํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ๋ฐ๋์ ํจ์จ์ ์ด์ง๋ ์์
- ์ธ๋ฑ์ค๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ์ฝ๋ ์ธ๋ฑ์ค ํ ์ค์บ์ ์๋ฏธํจ
- ์ธ๋ฑ์ค๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ ํ์ผ ์ ์ฒด๋ณด๋ค ํฌ๊ธฐ๊ฐ ์์ผ๋ฏ๋ก ์ธ๋ฑ์ค ํ ์ค์บ์ ํ ํ ์ด๋ธ ์ค์บ๋ณด๋ค ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋ฉฐ, ์ฟผ๋ฆฌ์ ๋ด์ฉ์ ๋ฐ๋ผ ์ ๋ ฌ๋ ์ธ๋ฑ์ค์ ์ฅ์ ์ ์ฌ์ฉํ ์ ์๊ธฐ์ ํจ์จ์ ์ด๋ผ ํ ์ ์๋ค.
- ๋ค์ ์กฐ๊ฑด ์ค (1,2) ์ถฉ์กฑ ํน์ (1,3) ์กฐ๊ฑด์ ์ถฉ์กฑํ๋ ์ฟผ๋ฆฌ์์ ์ฌ์ฉ๋๋ ์ฝ๊ธฐ ๋ฐฉ์
- range๋ const, ref ๊ฐ์ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ
- ์ธ๋ฑ์ค์ ํฌํจ๋ ์นผ๋ผ๋ง์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ์ฟผ๋ฆฌ์ธ ๊ฒฝ์ฐ(ํ ์ด๋ธ ํ ์ค์บ์ ์ํด๋ ๋๋ ๊ฒฝ์ฐ)
- ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์ ๋ ฌ์ด๋ ๊ทธ๋ฃจํ ์์ ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ(๋ณ๋ ์ ๋ ฌ ์์ ์ ํผํ ์ ์๋ ๊ฒฝ์ฐ)
5.12 ALL
- ํ ํ ์ด๋ธ ์ค์บ์ ์๋ฏธํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ
- ํ ์ด๋ธ์ ์ฒ์๋ถํฐ ๋๊น์ง ์ ๋ถ ์ฝ์ด์ ๋ถํ์ํ ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฐํ
- ์์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ ๋ ๊ฐ์ฅ ๋ง์ง๋ง์ ์ ํํ๋ ๊ฐ์ฅ ๋นํจ์จ์ ์ธ ๋ฐฉ๋ฒ
- ํ ์ด๋ธ์ด ๋งค์ฐ ์์ง ์๋ค๋ฉด ์ค์ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ ์ ๋ ์ ์ฅํ ์ํ์์ ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ ํ์ธํด๋ณด๊ณ ์ ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
๐ 6. possible_keys
- ์ตํฐ๋ง์ด์ ๊ฐ ์ต์ ์ ์คํ ๊ณํ์ ๋ง๋ค๊ธฐ ์ํด ํ๋ณด๋ก ์ ์ ํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ์์ ์ฌ์ฉ๋๋ ์ธ๋ฑ์ค์ ๋ชฉ๋ก
- “์ฌ์ฉ๋ ๋ฒํ๋ ์ธ๋ฑ์ค์ ๋ชฉ๋ก”์ด๋ฉฐ ๋ฐ๋์ ์ฌ์ฉ๋ ๊ฒ์ ์๋
- ์คํ ๊ณํ์์ ํน๋ณํ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ ๋ ๊ทธ๋ฅ ๋ฌด์ํ์.
๐ 7. key
- key ์นผ๋ผ์ ํ์๋๋ ์ธ๋ฑ์ค๋ ์ต์ข ์ ํ๋ ์คํ ๊ณํ์์ ์ฌ์ฉ๋๋ ์ธ๋ฑ์ค
- ์ฟผ๋ฆฌ ํ๋ ์ key ์นผ๋ผ์ ์๋ํ๋ ์ธ๋ฑ์ค๊ฐ ํ์๋๋์ง ํ์ธํ๋ ๊ฒ์ด ์ค์ํจ
- ์คํ ๊ณํ์ type์ด ALL์ผ ๋์ ๊ฐ์ด ์ธ๋ฑ์ค๋ฅผ ์ ํ ์ฌ์ฉํ์ง ๋ชปํ๋ฉด NULL๋ก ํ์๋จ
๐ 8. key_len ์นผ๋ผ
- ์ ํ๋ ์ธ๋ฑ์ค์ ๊ธธ์ด๋ฅผ ํ์
- ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ค์ค ์นผ๋ผ์ผ๋ก ๊ตฌ์ฑ๋ ์ธ๋ฑ์ค์์ ๋ช ๊ฐ์ ์นผ๋ผ๊น์ง ์ฌ์ฉํ๋์ง ํ๊ธฐ
- ๋ ์ ํํ๊ฒ๋ ์ธ๋ฑ์ค์ ๊ฐ ๋ ์ฝ๋์์ ๋ช ๋ฐ์ดํธ๊น์ง ์ฌ์ฉํ๋์ง ์๋ ค์ฃผ๋ ๊ฐ
๐ 9. ref
- ์ ๊ทผ ๋ฐฉ๋ฒ์ด ref๋ฉด ์ฐธ์กฐ ์กฐ๊ฑด(equal ๋น๊ต ์กฐ๊ฑด)์ผ๋ก ์ด๋ค ๊ฐ์ด ์ ๊ณต๋๋์ง ํ์
- ์์ซ๊ฐ → const, ๋ค๋ฅธ ํ ์ด๋ธ์ ์นผ๋ผ๊ฐ์ด๋ฉด ๊ทธ ํ ์ด๋ณ๋ช ๊ณผ ์นผ๋ผ๋ช ์ด ํ์
- ์กฐ์ธ ์นผ๋ผ์ ํ์ (NUMBER, VARCHAR ๋ฑ)์ ๋์ผํ๊ฒ ์ผ์น์ํค๋ ํธ์ด ์ข๋ค.
- ํฌ๊ฒ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋ฌด๋ฐฉํจ
๐ 10. rows
- ์คํ ๊ณํ์ ํจ์จ์ฑ ํ๋จ์ ์ํด ์์ธกํ๋ ๋ ์ฝ๋ ๊ฑด์๋ฅผ ๋ณด์ฌ์ค๋ค.
- ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ผ๋ง๋ ๋ง์ ๋ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ฒดํฌํด์ผ ํ๋์ง๋ฅผ ์๋ฏธํจ
- ํต๊ณ ๊ฐ์ผ๋ก ๊ณ์ฐํ ๊ฐ์ด๋ฏ๋ก ์ค์ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๋ฐํ๋ ๋ ์ฝ๋ ๊ฑด์๋ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
๐ 11. filtered
- ํํฐ๋ง๋๊ณ ๋จ์ ๋ ์ฝ๋์ ๋น์จ
- ํต๊ณ ๊ฐ ๋ฐํ์ผ๋ก ๊ณ์ฐํ ๊ฐ์ผ๋ก ์ค์ ๊ฒฐ๊ณผ ๊ฐ๊ณผ ๋ฐ๋์ ์ผ์นํ์ง ์๋๋ค.
๐ 12. Extra
- ์ฟผ๋ฆฌ ์คํ ๊ณํ์์ ์ฑ๋ฅ์ ๊ด๋ จ๋ ์ค์ํ ๋ด์ฉ์ด Extra ์นผ๋ผ์ ์์ฃผ ํ์๋จ
- ๋ด๋ถ์ ์ธ ์ฒ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์กฐ๊ธ ๋ ๊น์ด์๋ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
- ์ตํฐ๋ง์ด์ ๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง์ ๋ํด ์๋ ค์ฃผ๋ ํํธ ๊ฐ
12.1 Using filesort
- ORDER BY ์ฒ๋ฆฌ๊ฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ ๋ ์คํ ๊ณํ์ Extra ์นผ๋ผ์ “Using filesort” ํ์
- ์ด๋ ์กฐํ๋ ๋ ์ฝ๋๋ฅผ ์ ๋ ฌ์ฉ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ์ ๋ณต์ฌํด ํต ์ํธ ๋๋ ํ ์ํธ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด ์ ๋ ฌ ์ํ
- ORDER BY๊ฐ ์ฌ์ฉ๋ ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์์๋ง ๋ํ๋ ์ ์์
- Using filesort๊ฐ ์ถ๋ ฅ๋๋ ์ฟผ๋ฆฌ๋ ๋ง์ ๋ถํ๋ฅผ ์ผ์ผํค๋ฏ๋ก ๊ฐ๋ฅํ๋ค๋ฉด ์ฟผ๋ฆฌ๋ฅผ ํ๋ํ๊ฑฐ๋ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข์
12.2 Using index(์ปค๋ฒ๋ง ์ธ๋ฑ์ค)
๋ฐ์ดํฐ ํ์ผ์ ์ ํ ์ฝ์ง ์๊ณ ์ธ๋ฑ์ค๋ง ์ฝ์ด์ ์ฟผ๋ฆฌ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ ํ์
์ต์ ์ ๊ฒฝ์ฐ ์ธ๋ฑ์ค๋ฅผ ํตํด ๊ฒ์๋ ๊ฒฐ๊ณผ ๋ ์ฝ๋ ํ ๊ฑด์ฉ ๋์คํฌ๋ฅผ ์ฝ์ด์ผ ํ ์ ์๋ค.
์ ์ฟผ๋ฆฌ๊ฐ ๋ง์ฝ ์ธ๋ฑ์ค(ix_firstname)๋ฅผ ์ฌ์ฉํ๋ค๋ฉด employees ํ ์ด๋ธ์ first_name ์นผ๋ผ์ ์์ฑ๋ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์ผ์นํ๋ ๋ ์ฝ๋ ๊ฑด์๋ฅผ ๊ฒ์ํ๊ณ , ๊ฐ ๋ ์ฝ๋์ birth_date ์นผ๋ผ์ ๊ฐ์ ์ฝ๊ธฐ ์ํด ๊ทธ ๋งํผ ์ถ๊ฐ์ ์ผ๋ก ๋ฐ์ดํฐ ํ์ด์ง๋ฅผ ์ฝ์ด์ผ ํ๋ค.
๊ทธ๋์ MySQL ์ตํฐ๋ง์ด์ ๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํ ํ ์ด๋ธ ์ค์บ์ผ๋ก ์ฒ๋ฆฌํ๋ ํธ์ด ๋ ํจ์จ์ ์ด๋ผ๊ณ ํ๋จํ ๊ฒ์ด๋ค.
ํ์ง๋ง ์ ์ฟผ๋ฆฌ์ฒ๋ผ SELECT ์กฐํ ์นผ๋ผ์ birth_date ์นผ๋ผ์ ์ ์ธํ๋ฉด ํ ํ ์ด๋ธ ์ค์บ์ด ์๋ ์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ์ผ๋ก ์ฒ๋ฆฌ๊ฐ ๋๋ค.
์ ์ฟผ๋ฆฌ๋ ์ธ๋ฑ์ค๋ฅผ ํตํด ํ์ํ ๋ ์ฝ๋๋ฅผ ๊ฒ์ํ๊ณ ํ์ํ ์นผ๋ผ(first_name)๊น์ง ์ธ๋ฑ์ค์์ ๊ฐ์ ธ์ฌ ์ ์๋ค. ํ์ํ ์นผ๋ผ์ด ๋ชจ๋ ์ธ๋ฑ์ค์ ์์ผ๋ฏ๋ก ๋งค์ฐ ๋น ๋ฅธ ์๋๋ก ์ฒ๋ฆฌ๋๋ค.
์์ ๊ฐ์ด ์ธ๋ฑ์ค๋ง์ผ๋ก ์ฟผ๋ฆฌ ์ํ์ด ๊ฐ๋ฅํ ๋ ์คํ ๊ณํ์ Extra์๋ "Using index"๋ผ๋ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๊ณ , ์ด๋ ๊ฒ ์ธ๋ฑ์ค๋ง์ผ๋ก ์ฒ๋ฆฌ๋๋ ๋ฐฉ๋ฒ์ "์ปค๋ฒ๋ง ์ธ๋ฑ์ค(Covering Index)"๋ผ๊ณ ํ๋ค.
์ธ๋ฑ์ค ๋ ์ธ์ง ์ค์บ์ ์ฌ์ฉํ์ง๋ง ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ด ๋ง์กฑ์ค๋ฝ์ง ๋ชปํ ๊ฒฝ์ฐ ์ ๋ ๋ฒ์งธ ์์ ์ฒ๋ผ ์ธ๋ฑ์ค์ ์๋ ์นผ๋ผ๋ง ์ฌ์ฉํ๋๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ์ฌ ํฐ ์ฑ๋ฅ ํฅ์์ ๋ณผ ์ ์๋ค.
(์ฟผ๋ฆฌ๋ฅผ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ก ์ฒ๋ฆฌํ๋๋ ๋ชปํ๋๋์ ์ฑ๋ฅ ์ฐจ์ด๋ ์์ญ ๋ฐฐ์์ ์๋ฐฑ ๋ฐฐ๊น์ง ๋ ์ ์๋ค๊ณ ํ๋ค.)
12.3 Using temporary
์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋์ ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ๋๊ธฐ ์ํด ์์ ํ ์ด๋ธ(Temporary Table)์ ์์ฑํ์ฌ ํ์๋ ๊ฒ์ ์๋ฏธํ๋ค.
12.4 Using index for skip scan
MySQL ์ตํฐ๋ง์ด์ ๊ฐ ์ธ๋ฑ์ค ์คํต ์ค์บ ์ต์ ํ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ "Using index for skip scan"
๐ก index skip scan
์๋ฅผ ๋ค์ด, employees ํ ์ด๋ธ์์ (gender, birth_date) ์นผ๋ผ์ผ๋ก ์ด๋ฃจ์ด์ง ix_gb ์ธ๋ฑ์ค๊ฐ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
MySQL 8.0 ๋ฒ์ ๋ถํฐ WHERE ์กฐ๊ฑด์ ์ ์ธ๋ฑ์ค์ ์ ํ ์นผ๋ผ์ธ gender ์กฐ๊ฑด์ด ์์ด birth_date ์นผ๋ผ์ผ๋ก๋ง ์ด๋ฃจ์ด์ง ์ฟผ๋ฆฌ๊ฐ ์กด์ฌํ๋๋ผ๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค.
// ๊ธฐ์กด์๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ์์
SELECT * FROM employees WHERE birth_date >= '2001-02-04';
// skip scan์ ๋๋ต์ ์ผ๋ก ์๋์ ๊ฐ์ด ์ฟผ๋ฆฌ๊ฐ ์ฒ๋ฆฌ๋จ
SELECT * FROM employees WHERE gender = 'M' AND birth_date >= '2001-02-04';
SELECT * FROM employees WHERE gender = 'F' AND birth_date >= '2001-02-04';
* ํ์ง๋ง WHERE ์กฐ๊ฑด์ ์ ์๋ gender ์นผ๋ผ์ ์ ๋ํฌํ ๊ฐ์ ๊ฐ์๊ฐ ์ ์ด์ผ ํ๋ค๋ ๋จ์ ์ด ์๋ค.
(์์์๋ 'M', 'F' 2๊ฐ๋ง ์กด์ฌ)
12.5 Using join buffer(Block Nested Loop, hash join)
๋ณดํต ๋น ๋ฅธ ์ฟผ๋ฆฌ ์คํ์ ์ํด ์กฐ์ธ๋๋ ์นผ๋ผ์๋ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ค.
์ค์ ์กฐ์ธ์ ํ์ํ ์ธ๋ฑ์ค๋ ์กฐ์ธ์์ ๋ค์ ์ฝ๋ ํ ์ด๋ธ(๋๋ฆฌ๋ธ ํ ์ด๋ธ)์ ์นผ๋ผ์๋ง ํ์ํ๋ค.
(๋ค์ ์ฝ๋ ํ ์ด๋ธ์ ๊ฒ์ ์์ฃผ๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค๊ฐ ์์ผ๋ฉด ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ด ํฌ๊ธฐ ๋๋ฌธ)
์ด์ฒ๋ผ ์กฐ์ธ์ด ์ํ๋ ๋ ๋๋ฆฌ๋ธ ํ ์ด๋ธ์ ์ ์ ํ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด, MySQL ์ตํฐ๋ง์ด์ ๋ ๋ธ๋ก ๋ค์คํฐ๋ ๋ฃจํ๋ ํด์ ์กฐ์ธ์ ์ฌ์ฉํ๋ค.
์ด๋ MySQL ์๋ฒ์ join buffer๋ฅผ ์ฌ์ฉํ๋ค. (join_buffer_size๋ผ๋ ์์คํ ๋ณ์๋ฅผ ํตํด ์กฐ์ธ ๋ฒํผ์ ํฌ๊ธฐ ์ค์ ์ด ๊ฐ๋ฅํ๋ค.)
12.6 Using where
์ฟผ๋ฆฌ์ ๋ํ ์ ๊ทผ ๋ฐฉ์์ ์ค๋ช ํ ๊ฒ์ผ๋ก ์คํ ๋ฆฌ์ง ์์ง์ผ๋ก ๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ MySQL ์์ง์์ ๋ณ๋์ ๊ฐ๊ณต์ ํด์ ํํฐ๋ง ์์ ์ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ Extra ์นผ๋ผ์ "Using where" ํ์
์์ ๋ก ์ฌ์ฉ๋ ์ฟผ๋ฆฌ
-- EXPLAIN
-- SELECT *
-- FROM employees e
-- INNER JOIN salaries s ON e.emp_no = s.emp_no
-- WHERE first_name = 'ABC';
-- id, SIMPLE
EXPLAIN
SELECT e.*
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no;
EXPLAIN
SELECT e.*
FROM employees e
INNER JOIN salaries s ON s.emp_no = e.emp_no;
-- id, PRIMARY
EXPLAIN
SELECT
( (SELECT COUNT(*) FROM employees) + (SELECT COUNT(*) FROM salaries) ) AS total_count
FROM employees;
-- Subquery
EXPLAIN
SELECT
e.first_name,
(SELECT COUNT(*) FROM salaries LIMIT 3) AS cnt
FROM employees e
WHERE e.emp_no = 3;
-- Union
EXPLAIN
SELECT *
FROM (
(SELECT emp_no FROM employees e1 LIMIT 2) UNION ALL
(SELECT emp_no FROM employees e2 LIMIT 2) UNION ALL
(SELECT emp_no FROM employees e3 LIMIT 3)
) tb;
-- Dependent Union
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'
);
-- Subquery
EXPLAIN
SELECT
e.first_name,
(SELECT COUNT(*) FROM salaries LIMIT 3) AS cnt
FROM employees e
WHERE e.emp_no = 3;
-- Derived
EXPLAIN
SELECT *
FROM ( SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE e.emp_no = tb.emp_no;
-- Derived join
EXPLAIN
SELECT *
FROM employees e
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;
-- Materialized
EXPLAIN
SELECT *
FROM employees e
WHERE e.emp_no IN (
SELECT emp_no FROM salaries WHERE amount BETWEEN 100 AND 1000
);
EXPLAIN
SELECT NOW();
SELECT *
FROM ( SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE tb.emp_no = e.emp_no;
SELECT * FROM employees e
WHERE e.emp_no IN (
SELECT emp_no FROM salaries WHERE amount BETWEEN 12000 AND 16000
);
SELECT * FROM salaries;
CREATE TABLE employees_partitions(
emp_no int NOT NULL AUTO_INCREMENT,
birth_date DATE NOT NULL,
first_name VARCHAR(16) NOT NULL,
last_name VARCHAR(16) NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no, hire_date)
) PARTITION BY RANGE COLUMNS(hire_date)
(
PARTITION p2000 VALUES LESS THAN ('2000-01-01'),
PARTITION p2005 VALUES LESS THAN ('2005-01-01'),
PARTITION p2010 VALUES LESS THAN ('2010-01-01'),
PARTITION p2015 VALUES LESS THAN ('2015-01-01'),
PARTITION p2020 VALUES LESS THAN ('2020-01-01')
);
INSERT INTO employees_partitions VALUES (null, "2022-12-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-11-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-10-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-09-30", 'JH', 'Lee', '2019-12-30');
INSERT INTO employees_partitions VALUES (null, "2022-08-30", 'JH', 'Lee', '2019-12-30');
SELECT * FROM employees_partitions;
-- partitions
EXPLAIN
SELECT *
FROM employees_partitions
WHERE hire_date BETWEEN '2014-01-06' AND '2022-12-30';
-- MyISAM -> system
CREATE TABLE employees_2(
emp_no int NOT NULL AUTO_INCREMENT PRIMARY KEY,
birth_date DATE NOT NULL,
first_name VARCHAR(16) NOT NULL,
last_name VARCHAR(16) NOT NULL
) ENGINE = MyISAM;
INSERT INTO employees_2 VALUES (null, '2022-12-30', 'a', 'b');
commit;
EXPLAIN SELECT * FROM employees_2;
-- InnoDB -> ALL
CREATE TABLE employees_3(
emp_no int NOT NULL AUTO_INCREMENT PRIMARY KEY,
birth_date DATE NOT NULL,
first_name VARCHAR(16) NOT NULL,
last_name VARCHAR(16) NOT NULL
) ENGINE = InnoDB;
INSERT INTO employees_3 VALUES (null, '2022-12-30', 'a', 'b');
commit;
EXPLAIN SELECT * FROM employees_3;
SELECT * FROM employees;
-- const
EXPLAIN SELECT * FROM employees WHERE emp_no = 4 AND hire_date = '2000-01-01';
EXPLAIN SELECT * FROM salaries WHERE sal_id = 2;
EXPLAIN
SELECT *
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no
AND s.sal_id = 2;
-- ref
EXPLAIN
SELECT * FROM employees e WHERE e.emp_no = 3;
-- ALL
EXPLAIN
SELECT * FROM salaries s WHERE s.emp_no = 3;
-- const
EXPLAIN
SELECT * FROM salaries s WHERE s.sal_id = 2;
SELECT * FROM salaries;
INSERT INTO salaries VALUES (6, null, 8000);
-- unique_subquery
EXPLAIN
SELECT * FROM employees
WHERE emp_no IN (
SELECT emp_no FROM salaries WHERE sal_id = 3
);
-- const, ref (MySQL ๋ฒ์ 5.x -> unqiue_subquery)
EXPLAIN
SELECT * FROM employees
WHERE emp_no IN (
SELECT emp_no FROM salaries WHERE sal_id = 3
);
-- range
EXPLAIN
SELECT * FROM employees
WHERE emp_no BETWEEN 2 AND 6;
-- range
EXPLAIN
SELECT * FROM salaries
WHERE amount BETWEEN 9000 AND 14000;
SELECT * FROM employees;
SELECT * FROM salaries;
EXPLAIN
SELECT * FROM employees ORDER BY last_name LIMIT 5;
EXPLAIN
SELECT * FROM employees ORDER BY emp_no LIMIT 5;
EXPLAIN
SELECT * FROM employees ORDER BY hire_date LIMIT 5;
EXPLAIN
SELECT * FROM employees ORDER BY emp_no, hire_date LIMIT 5;
EXPLAIN
SELECT * FROM salaries ORDER BY sal_id;
EXPLAIN
SELECT * FROM salaries ORDER BY emp_no;
EXPLAIN
SELECT * FROM employees;
-- key_len
EXPLAIN
SELECT * FROM dept_emp WHERE dept_no = 1 AND emp_no = '3';
SELECT * FROM dept_emp;
-- ref
SELECT *
FROM employees e, dept_emp de
WHERE e.emp_no = de.emp_no;
-- ์ด ๋ฐ์ดํฐ: 450๋ง๊ฑด
EXPLAIN
SELECT * FROM salaries WHERE amount > 2000 AND sal_id > 10000;
EXPLAIN
SELECT * FROM salaries WHERE emp_no = 1;
EXPLAIN
SELECT * FROM dept_emp WHERE dept_no > 3;
-- 25๊ฑด ์ค 10๊ฑด ์กฐํ
EXPLAIN
SELECT * FROM employees_partitions WHERE hire_date > '2014-12-01';
-- 5๊ฑด, 33.33
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2014-12-01';
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20;
-- 10
SELECT * FROM employees_partitions WHERE hire_date > '2014-12-01';
-- 5๊ฑด, row:5, filter: 100
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20;
-- 2๊ฑด, row:4, filter:33.33
EXPLAIN
SELECT * FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2019-12-01';
SELECT COUNT(*) FROM employees_partitions WHERE emp_no > 20;
SELECT COUNT(*) FROM employees_partitions WHERE emp_no > 20 AND hire_date > '2019-12-01';
EXPLAIN
SELECT * FROM salaries ORDER BY amount;
EXPLAIN
SELECT e.*
FROM employees e, salaries s
WHERE e.emp_no = s.emp_no;
EXPLAIN
SELECT e.*
FROM employees e
INNER JOIN salaries s ON e.emp_no = s.emp_no;
-- Derived
EXPLAIN
SELECT *
FROM (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb,
employees e
WHERE e.emp_no = tb.emp_no;
-- Join
EXPLAIN
SELECT *
FROM employees e
-- JOIN ์ ์์ ์๋ธ์ฟผ๋ฆฌ ์ฌ์ฉ
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;
EXPLAIN
SELECT *
FROM employees e
-- JOIN ์ ์์ ์๋ธ์ฟผ๋ฆฌ ์ฌ์ฉ
JOIN (SELECT s.emp_no FROM salaries s GROUP BY s.emp_no) tb
ON e.emp_no = tb.emp_no;
EXPLAIN FORMAT=TREE
SELECT *
FROM dept_emp de, employees e
WHERE e.emp_no = de.emp_no
AND de.dept_no = '1';
SELECT VERSION();
EXPLAIN
SELECT * FROM employees_partitions WHERE hire_date LIKE '2010%';
SELECT COUNT(*) FROM employees;
INSERT INTO employees VALUES (3, '2002-01-02', 'Hali', 'A', 'M', '2009-04-01', '2');
EXPLAIN
SELECT first_name
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';
EXPLAIN
SELECT first_name, birth_date
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';
EXPLAIN
SELECT emp_no, first_name
FROM employees WHERE first_name BETWEEN 'Jade' AND 'Neo';
๐ ์ฐธ๊ณ ๋ฌธ์
'CS > Database' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ ๋ฌด์ ๋ฐ๋ก ์ฐ๋ SQL ํ๋ 2 - SQL ํ๋ ์ค์ต (1) (0) | 2024.10.08 |
---|---|
์ ๋ฌด์ ๋ฐ๋ก ์ฐ๋ SQL ํ๋ 1 - SQL ํ๋ ์ด๋ก (1) | 2024.10.07 |
[Spring Data MongoDB] - Auto Increment Sequence ์ด๊ธฐํํ๊ธฐ (0) | 2021.09.11 |
[Spring Data MongoDB] Auto-Increment Sequence ๋ง๋ค๊ธฐ (0) | 2021.09.10 |
[MySQL] - ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค(Isolation level) (11) | 2021.09.05 |
๋๊ธ