Real MySQL 8.0 10์ฅ ์คํ๊ณํ์ 150๋ง๊ฐ์ ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํด ๊ณต๋ถํ๋ฉฐ ์์ฑํ ๊ธ์ ๋๋ค.
"์คํ ๊ณํ์ ์ด๋ป๊ฒ ์ฝ์ด์ผ ํ๋์ง, ๋ฌด์์ ์ฝ์ด์ผ ํ๋์ง?" ์ ๋ํด ์ ๊ฐ์ธ์ ์ธ ์๊ฒฌ์ด ๋ค์ด๊ฐ์์ ๋ฐํ๋ฉฐ, ๋ถ์กฑํ ๋ถ๋ถ์ด ์์์ ๋ฏธ๋ฆฌ ์ํด ๊ตฌํฉ๋๋ค.
1. ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ๋ ๊ณ ๋ คํ๋ ๊ธฐ์ค
์ ๋ ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ์ปฌ๋ผ์ ์ ํํ ๋ ๋ค์ 3๊ฐ์ง ๊ธฐ์ค์ ์ฃผ๋ก ๊ณ ๋ คํฉ๋๋ค.
* ์ถ๊ฐ๋ก, ์ธ๋ฑ์ค ์ค์ ์ ์ฃผ์ํ ์ ๋ค์ ํด๋น ๋ชฉ์ฐจ ๋ฒ์๋ฅผ ๋ฒ์ด๋จ์ผ๋ก ์๋ตํ๊ฒ ์ต๋๋ค!
โ ์นด๋๋๋ฆฌํฐ(Cardinality)๊ฐ ๋์ ์ปฌ๋ผ์ธ๊ฐ?
- ์นด๋๋๋ฆฌํฐ๋ ํด๋น ์ปฌ๋ผ์ ๊ณ ์ ๊ฐ ์๋ฅผ ์๋ฏธํฉ๋๋ค.
- InnoDB ๊ฐ ๋ ์ฝ๋๋ฅผ ์ฝ์ ๋, ์นด๋๋๋ฆฌํฐ๊ฐ ๋์์๋ก ๋น ๋ฅด๊ฒ ๋ ์ฝ๋๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์, ์นด๋๋๋ฆฌํฐ๊ฐ ๋์ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ๋ ์ฐ์ ๊ณ ๋ คํฉ๋๋ค.
โ UPDATE/DELETE ์ฟผ๋ฆฌ์ WHERE ์ ์ ์์ฃผ ์ฌ์ฉ๋๋ ์ปฌ๋ผ์ธ๊ฐ?
- UPDATE๋ DELETE ์ฟผ๋ฆฌ์์ WHERE ์ ์ ์ฌ์ฉ๋๋ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ์์ผ๋ฉด InnoDB๊ฐ ๋ ์ฝ๋๋ฅผ ์ฐพ์ผ๋ฉด์ ๋ถํ์ํ ๋ ์ฝ๋์ ๋ฐฐํ ๋ฝ์ด ๊ฑธ๊ฒ ๋ฉ๋๋ค.
- ๋ฐ๋ผ์, WHERE ์ ์์ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ๋๋ ์ปฌ๋ผ์ด๋ผ๋ฉด ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ์ฌ ๋ถํ์ํ ๋ ์ฝ๋์ ๋ฝ์ด ๊ฑธ๋ฆฌ๋ ๊ฒ์ ๋ฐฉ์งํด์ผ ํฉ๋๋ค.
โ ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค ์ค์ ์, ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๋น๊ต๋๋ ์ปฌ๋ผ์ ์ ์์์ ์ค์ ํฉ๋๋ค.
- ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ๋๋ ๋๋ฑ ์กฐ๊ฑด(= ๋น๊ต, IN์ )์ผ๋ก ์์ฃผ ๋น๊ต๋๋ ์ปฌ๋ผ์ ์ ์์์ ์ค์ ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค์ด WHERE ์ ์ ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ๋ ๊ฒฝ์ฐ, ๋๋ฑ ์กฐ๊ฑด์์ ์ธ๋ฑ์ค๋ ๋ฒ์ ๊ฒฐ์ ์กฐ๊ฑด์ผ๋ก ์๋ํฉ๋๋ค. ๋ฐ๋ฉด, ๋ฒ์ ์กฐ๊ฑด์ด ๋จผ์ ๋์ค๊ณ ๊ทธ ์ดํ์ ๋๋ฑ ์กฐ๊ฑด์ด ์ค๋ ๊ฒฝ์ฐ, ๋๋ฑ ์กฐ๊ฑด์ ๋จ์ํ ํํฐ๋ง ์ญํ ์ ๊ทธ์น๊ฒ ๋ฉ๋๋ค.
์ด์ฒ๋ผ ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ๋ ์ฌ๋ฌ ๊ธฐ์ค์ ๊ณ ๋ คํ์ง๋ง, ์ค์ ์ฟผ๋ฆฌ ์ฑ๋ฅ์ ์คํ ๊ณํ์ ํตํด ์ง์ ํ์ธํด์ผ ํฉ๋๋ค.
์คํ ๊ณํ์ ๋ถ์ํ๋ฉด ์ค์ ํ ์ธ๋ฑ์ค๊ฐ ์ ๋๋ก ํ์ฉ๋๋์ง, ์ฟผ๋ฆฌ๊ฐ ์ต์ ํ๋์ด ์๋์ง๋ฅผ ๋ช
ํํ๊ฒ ์ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
2. ์คํ ๋ฐ์ดํฐ ์์ฑ ๋ฐ ์คํ ์๊ฐ
์ด๋ฌํ ์ด์ ๋ก ์คํ ๊ณํ์ ๋ํด ๊ณต๋ถํ๊ฒ ๋์๊ณ , ์ค์ ์คํ ๊ณํ์ ์ฝ๊ณ ํด์ํ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์คํ ๊ณํ์์ ๋ฌด์์ ์ค์ ์ ์ผ๋ก ๋ด์ผ ํ๋์ง์ ๋ํด ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ์ง์ ๋ถ์ํ๊ณ , ์ ๊ฐ ๋๋ ์ ๊ณผ ๊นจ๋ฌ์ ๋ด์ฉ์ ๊ณต์ ํ๊ณ ์ ํฉ๋๋ค.
ํ ์คํธ๋ฅผ ์ํด letter ํ ์ด๋ธ์๋ ์ฝ 150๋ง ๊ฑด์ ๋ ์ฝ๋๋ฅผ, reply ํ ์ด๋ธ์๋ ์ฝ 10๋ง ๊ฑด์ ๋ ์ฝ๋๋ฅผ ๋๋ฏธ ๋ฐ์ดํฐ๋ก ์์ฑํ์ฌ ์คํ์ ์งํํ์ต๋๋ค.
์กฐํ ๋์์ ํน์ ์ ์ ๊ฐ ์ง๋ ํ ๋ฌ ๋์ ์์ฑํ ํธ์ง ์ค ๋ฐํ๋ ํธ์ง์ด๋ฉฐ, ๊ฒฐ๊ณผ๋ ์์ฑ์ผ(created_at) ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํ์ฌ ์ต์ 3๊ฐ์ ๋ ์ฝ๋๋ง ๊ฐ์ ธ์ต๋๋ค.
SELECT l.*
FROM letter l
JOIN reply r ON l.letter_id = r.letter_id
WHERE l.created_at BETWEEN '2024-10-01 00:00:18.000000' AND '2024-11-01 00:00:18.000000'
AND l.published = true
AND l.user_id = UUID_TO_BIN('6f296420-23c1-4e0d-a9cb-a7cb85b1c76c')
ORDER BY l.created_at DESC
LIMIT 3;
MySQL์ ์ตํฐ๋ง์ด์ ๋ ํต๊ณ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์คํ ๊ณํ์ ์๋ฆฝํฉ๋๋ค. ์ตํฐ๋ง์ด์ ๊ฐ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ์ ์ต์ ํต๊ณ ์ ๋ณด๋ฅผ ์ ์ ์๋๋ก ๋ ํ ์ด๋ธ์ ํต๊ณ ์ ๋ณด๋ฅผ ์ต์ ํ ํด์ฃผ๊ฒ ์ต๋๋ค.
ANALYZE TABLE letter;
ANALYZE TABLE reply;
์ด์ EXPLAIN ๋ช ๋ น์ด๋ฅผ ํตํด ์คํ ๊ณํ์ ํ์ธํ๊ณ , ๊ฐ ์ปฌ๋ผ์ด ์๋ฏธํ๋ ๋ฐ๋ฅผ ํด์ํ๋ฉด์ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํด ๋ณด๊ฒ ์ต๋๋ค.
์คํ ๊ณํ์ ๊ณต๋ถํ ๊ฒฐ๊ณผ, ์คํ ๊ณํ์์ ์ค์ํ๊ฒ ๋ด์ผํ๋ ์ปฌ๋ผ์ type / key / key_len / rows / filtered / Extra ์ ๋๋ค. ๊ทธ ์ด์ ์ ๋ํด ์ค๋ช ํด๋ณด๊ฒ ์ต๋๋ค.
3. Table ํํ์ ์คํ ๊ณํ ๋ถ์
โถ type ์ปฌ๋ผ: ๊ฐ ํ ์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ด๋ค ๋ฐฉ์์ผ๋ก ์ฝ์๋์ง
- letter ํ
์ด๋ธ (table ์์ l) : ref
- ref ๋ ์กฐ์ธ์ ์์์ ์ธ๋ฑ์ค์ ์ข ๋ฅ์ ๊ด๊ณ์์ด ๋๋ฑ ์กฐ๊ฑด์ผ๋ก ๊ฒ์ํ๋ค๋ ๊ฒ์ผ๋ก ํจ์จ์ ์ ๋๋ค.
- reply ํ
์ด๋ธ (table ์์ r) : eq_ref
- eq_ref ๋ ์กฐ์ธ๋๋ ์ฟผ๋ฆฌ์ ์คํ ๊ณํ์์๋ง ํ์๋๋ฉฐ, ์ฒซ ๋ฒ์งธ ์ฝ์ ํ ์ด๋ธ์ ์ปฌ๋ผ ๊ฐ์ ์ด์ฉํด ๋ ๋ฒ์งธ ํ ์ด๋ธ์ PK๋ ์ ๋ํฌ ํค๋ก ๋๋ฑ ์กฐ๊ฑด ๊ฒ์ํ ๋ ํ์๋ฉ๋๋ค.
- eq_ref ์์ ๋ ๋ฒ์งธ ํ ์ด๋ธ์ ๋ฐ๋์ 1๊ฑด์ ๋ ์ฝ๋๋ง ๋ฐํ๋๋ฏ๋ก ๋งค์ฐ ํจ์จ์ ์ ๋๋ค.
Real MySQL ์์๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์์ผ๋ก ์ฑ๋ฅ์ด ๋น ๋ฅด๋ค๊ณ ํฉ๋๋ค.(๋ค๋ก ๊ฐ์๋ก ๋๋ ค์ง)
const → eq_ref → ref → fulltext → ref_or_null → unique_subquery → index_subquery → range → index_merge → index → ALL
์ฌ๊ธฐ์, ๊ฐ์ฅ ๋ง์ง๋ง์ ์๋ ALL ์ด ์ธ๋ฑ์ค๋ฅผ ํ์ฉํ์ง ๋ชปํ ํ ์ด๋ธ ํ ์ค์บ์ด๋ฉฐ์ด๊ณ , index ๊ฐ ์ธ๋ฑ์ค ํ ์ค์บ์ ์๋ฏธํฉ๋๋ค. ์คํ ๊ณํ์ด ํด๋น ๊ฐ์ ๊ฐ์ง๋ค๋ฉด ์ธ๋ฑ์ค ๋ฐ ์ฟผ๋ฆฌ ์์ ์ด ํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
โถ key ์ปฌ๋ผ: ๋ ์ฝ๋๋ฅผ ์ฝ์ ๋ ์ฌ์ฉ๋ ์ธ๋ฑ์ค
MySQL์์๋ ํ ์ด๋ธ์ ์ฌ๋ฌ ๊ฐ์ ์ธ๋ฑ์ค๊ฐ ์์ด๋ ํ ๋ฒ์ ์ฟผ๋ฆฌ ์คํ ์ ๋จ ํ๋์ ์ธ๋ฑ์ค๋ง ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋์, key ์ปฌ๋ผ์ ํญ์ 1๊ฐ์ key ๋ง์ด ํ์๋ฉ๋๋ค.
์ด๋ฒ ์ฟผ๋ฆฌ์์๋ ๋ค์ ์ธ๋ฑ์ค๊ฐ ์ฌ์ฉ๋์์ต๋๋ค.
- letter ํ ์ด๋ธ: user_id (์ธ๋ ํค)
- reply ํ ์ด๋ธ: letter_id (์ ๋ํฌ ํค์ด์ ์ธ๋ ํค)
key ์ปฌ๋ผ์ ํตํด ์๋๋ ์ธ๋ฑ์ค๊ฐ ์ฐ์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
โถ key_len ์ปฌ๋ผ: ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค์์ ๋ช ๊ฐ์ ์ปฌ๋ผ์ด ์ฌ์ฉ๋์๋์ง
- ์ด๋ฒ ์ฟผ๋ฆฌ์์ ์ฌ์ฉ๋ letter ํ ์ด๋ธ์ FK(user_id)์ reply ํ ์ด๋ธ์ UK(letter_id)๋ UUID ํ์ ์ผ๋ก 16๋ฐ์ดํธ์ ๋๋ค.
- ๋ฐ๋ผ์, key_len ๊ฐ์ด 16์ผ๋ก ๋ํ๋๋ฉฐ, UUID ์ปฌ๋ผ ์ ์ฒด๊ฐ ์ธ๋ฑ์ค ์กฐ๊ฑด์ผ๋ก ์ฌ์ฉ๋์์์ ์๋ฏธํฉ๋๋ค.
key_len ์ปฌ๋ผ์ ํตํด ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค์์ ์ฌ์ฉ๋์ง ์์ ์ปฌ๋ผ์ ๊ตฌ๋ถํด์ ๋ถํ์ํ ์ปฌ๋ผ์ ๋ฉํฐ ์ปฌ๋ผ ์ธ๋ฑ์ค์์ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
โถ rows ์ปฌ๋ผ: InnoDB ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ผ๋ง๋ ๋ง์ ํ์ ์ฝ์ด์ผ ํ๋์ง
- ์ด๋ฒ ์ฟผ๋ฆฌ์์ ์ตํฐ๋ง์ด์ ๋ letter ํ ์ด๋ธ์์ 17๊ฐ ํ์ ์ฝ์ด์ผ ํ๋ค๊ณ ์์ธกํ์ต๋๋ค.
โถ filtered ์ปฌ๋ผ: MySQL์์ง์ด InnoDB๊ฐ ์ฝ์ ๋ ์ฝ๋ ์ค ์ธ๋ฑ์ค๋ฅผ ํ์ฉํ์ง ์๋ ์ปฌ๋ผ์ ์ํด ํํฐ๋ง๋ ๋ ์ฝ๋์ ๋น์จ
letter ํ ์ด๋ธ์์ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฝ์ด์ผ ํ ํ์ ์(rows)๋ 17๊ฐ์ ๋๋ค.
- ์ด ์ค l.created_at ์กฐ๊ฑด๊ณผ l.published = true ์กฐ๊ฑด์ ํตํด ํํฐ๋ง๋์ด reply ํ ์ด๋ธ์ JOIN ๋ ํ์ ๊ฐ์๋ 17 * 0.056 ์ธ ์ฝ 1๊ฐ๋ก ์์ธก๋ฉ๋๋ค.
โป rows์ filtered์ ์ค์์ฑ
์ด๋ฒ ์ฟผ๋ฆฌ์์๋ rows์ filtered ๊ฐ์ด ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ๊ฐ ์ด ๋ ์ปฌ๋ผ์ ์ค์ํ๊ฒ ๋ณด๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- rows ๊ฐ์ด ํฌ๊ณ , filtered ๊ฐ์ด ๋ฎ์ ๊ฒฝ์ฐ๋ ๋ถํ์ํ๊ฒ ๋ง์ ๋ ์ฝ๋๋ฅผ ์ฝ์๋ค๋ ์๋ฏธ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋ฅผ ๋ค์ด rows = 97,000, filtered = 10 ์ด ๋์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
- InnoDB๋ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด 97,000๊ฑด์ ๋ ์ฝ๋๋ฅผ ์ฝ์์ต๋๋ค.
- ๊ทธ๋ฌ๋ WHERE ์กฐ๊ฑด์ ํตํด ํํฐ๋ง๋ ๋ ์ฝ๋๋ 9,700๊ฑด(97,000 * 0.1)์ ๋ถ๊ณผํฉ๋๋ค.
์ฆ, ์ฝ 87,300๊ฑด์ ๋ ์ฝ๋๋ฅผ ๋ถํ์ํ๊ฒ ์ฝ์ ๊ฒ์ด๋ฏ๋ก, ์ด ๊ฒฝ์ฐ์๋ ์ฟผ๋ฆฌ ํ๋ ๋๋ ์ธ๋ฑ์ค ์์ ์ด ํ์ํ๋ค๊ณ ํ๋จํ ์ ์์ต๋๋ค.
โถ Extra ์ปฌ๋ผ: ์ฟผ๋ฆฌ์ ์ฑ๋ฅ๊ณผ ๊ด๋ จ๋ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณต
๋จผ์ letter ํ ์ด๋ธ์ Extra ์ปฌ๋ผ์ ํด์ํด๋ณด๊ฒ ์ต๋๋ค.
Using index condition;
- ์ด ๊ฐ์ ์ธ๋ฑ์ค์ ํฌํจ๋ ์ปฌ๋ผ์ด๋ผ๋ฉด InnoDB(์คํ ๋ฆฌ์ง ์์ง)์ผ๋ก ์ ๋ฌํ์ฌ ์ต๋ํ InnoDB์์ ๋ ์ฝ๋๋ฅผ ๊ฑธ๋ฌ์ MySQL ์์ง์ ์ฃผ๋๋ก ์ต์ ํ๋ ๊ธฐ๋ฅ์ผ๋ก MySQL ์ 5.6 ๊ธฐ์ค์ผ๋ก ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ ๋๋ค.
- ์ฆ, ํํฐ๋ง ์์ ์ MySQL ์์ง์์ ์ํํ์ง ์๊ณ , InnoDB์์ ์ฒ๋ฆฌํจ์ผ๋ก์จ ๋์คํฌ I/O๋ฅผ ์ค์ด๊ณ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค๊ฒ ์ต๋๋ค.
// ์ธ๋ฑ์ค
INDEX full_name (last_name, first_name)
// ์ฟผ๋ฆฌ
WHERE last_name = "์ข
ํ" and first_name LIKE "%์";
์ฒ๋ฆฌ ๊ณผ์
- ์ด ์ฟผ๋ฆฌ์์ InnoDB๋ last_name = '์ข ํ' ์กฐ๊ฑด์ ์ธ๋ฑ์ค(full_name)๋ฅผ ํตํด ๋น ๋ฅด๊ฒ ๊ฒ์ํ ์ ์์ต๋๋ค.
- ๊ทธ๋ฌ๋ first_name LIKE '%์' ์กฐ๊ฑด์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด MySQL 5.5 ๋ฒ์ ์ดํ์์๋ MySQL ์์ง์ด ์ง์ ํํฐ๋ง์ ์ํํ์ต๋๋ค.
- ์ด ๊ฒฝ์ฐ, InnoDB๊ฐ ๋ฐํํ ๋ ์ฝ๋๋ค์ MySQL ์์ง์ด ๋ค์ ๋์คํฌ I/O๋ฅผ ํตํด ํํฐ๋งํด์ผ ํ๋ฏ๋ก ๋นํจ์จ์ ์ด์์ต๋๋ค.
์ธ๋ฑ์ค ์ปจ๋์ ํธ์๋ค์ด(MySQL 5.6 ์ด์ ์ต์ ํ)
- ํ์ง๋ง, InnoDB ๊ฐ last_name ์ ์ฝ๊ธฐ ์ํด full_name ์ธ๋ฑ์ค๋ฅผ ์ฝ์ผ๋ฉฐ first_name ๋ ๊ฐ์ด ํํฐ๋ง ํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ๊ฒ์ ๋๋ค. ์ด์ฐจํผ full_name ์ธ๋ฑ์ค๋ฅผ ์ฝ์ํ ๋๊น์.
- ์ฆ, ์ธ๋ฑ์ค์ ํฌํจ๋ ํ๋๋ผ๋ฉด InnoDB ๋ก ์ ๋ฌํด์ ์ต๋ํ InnoDB ๊ฐ ๊ฑธ๋ฌ๋ผ ์ ์๋๋ก ์ธ๋ฑ์ค ์ปจ๋์ ํธ์๋ค์ด ๊ธฐ๋ฅ์ ์ด์ฉํด์ ์ธ๋ฑ์ค ์กฐ๊ฑด์ ๋ด๋ฆฌ๊ฒ ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋์คํฌI/O ๋ฅผ ์ค์ด๊ฒ ๋์์ต๋๋ค.
Using where;
์ด ๊ฐ์ MySQL์์ง์์ ํํฐ๋ง ์์ ์ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋ํ๋ฉ๋๋ค. ์ด Using where ์ด ์ฑ๋ฅ์ ์ข์์ง๋ filtered ์ปฌ๋ผ์ ๊ฐ์ด ๋ณด๋ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์๋ filtered ๊ฐ 5%์ด๋, 17(rows) * 0.05 ๋ฅผ ๊ณฑํ ๊ฐ์ธ ์ฝ 1๊ฑด์ด WHERE ์กฐ๊ฑด(ํํฐ๋ง ์์ )์ ๊ฒฐ๊ณผ์ ๋๋ค. ์ฆ, InnoDB ์ ๋ถํ์ํ๊ฒ ๋ ์ฝ๋๋ฅผ ์ฝ์ง ์์์ ๋ํ๋ ๋๋ค.
Using filesort;
์ด ๊ฐ์ ORDER BY ๊ฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ ๋ ํ์๋๋ฉฐ, ORDER BY๊ฐ ์ฌ์ฉ๋ ์ฟผ๋ฆฌ์์๋ง ๋ํ๋ฉ๋๋ค. Real MySQL ์์๋ ORDER BY๋ฅผ ํ๋ ๊ณผ์ ์์ ์ถ๊ฐ CPU์ฐ์ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋, ๋์คํฌ ์ ์ถ๋ ฅ์ ์ฆ๊ฐ์ํค๊ธฐ๋ฏ๋ก ์ฟผ๋ฆฌ๋ฅผ ํ๋ํ๊ฑฐ๋ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํฉ๋๋ค.
๊ฒฐ๊ตญ, Using filesort ๋ Extra ์ปฌ๋ผ์์ ์ ๊ฑฐํด์ฃผ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
4. Table ํํ์ ์คํ ๊ณํ ๋ถ์์ ๋ํ ๊ฒฐ๋ก
์ฌ๊ธฐ๊น์ง ํ ์ด๋ธ ํํ์ ์คํ ๊ณํ์ ๋ณด๋ฉฐ ์ตํฐ๋ง์ด์ ๊ฐ ์ด๋ป๊ฒ ๋ ์ฝ๋๋ฅผ ์ฝ๊ณ , ํจ์จ์ ์ผ๋ก ์ฝ๋์ง ์ ์ ์์์ต๋๋ค.
- key ์ key_len ์ ํตํด ์๋๋ ์ธ๋ฑ์ค๊ฐ ์ฐ์ด๋์ง
- type ์ ํตํด ์ธ๋ฑ์ค๊ฐ ์ด๋ป๊ฒ ์ฐ์ด๋์ง
- rows ์ filtered ๋ฅผ ํตํด ๋ถํ์ํ ํ์ ๋ง์ด ์ฝ์ง๋ ์๋์ง
- Extra ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ฟผ๋ฆฌ์ ์ถ๊ฐ์ ์ธ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ์ง
๋ฐ๋ผ์, ํ ์ด๋ธ ํํ์ ์คํ ๊ณํ์์๋ ์ด ์ฃผ์ ์ปฌ๋ผ๋ค์ ์ฃผ์ ๊น๊ฒ ๋ถ์ํ๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํ์ง๋ง, ์ฌ๊ธฐ์ ์ค์ํ ์ ์ ์คํ ๊ณํ์ ์ด๋๊น์ง๋ ์ตํฐ๋ง์ด์ ์ ์ถ์ธก์ผ ๋ฟ์ด๋ผ๋ ๊ฒ์ ๋๋ค. MySQL ์ตํฐ๋ง์ด์ ๊ฐ ์์ํ ์ฟผ๋ฆฌ ์ํ ๋ฐฉ์๊ณผ ์ค์ ์คํ ์์ ์ฑ๋ฅ์ ๋ค๋ฅผ ์ ์์ต๋๋ค. ๋ฐ๋ผ์, ์ฟผ๋ฆฌ๊ฐ ์ค์ ๋ก ์ด๋ป๊ฒ ์คํ๋๋์ง ํ์ธํ๋ ค๋ฉด ๋ฐ๋์ EXPLAIN ANALYZE๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ๋ถ์ํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด, filesort๊ฐ ์ค์ ๋ก ๋ง์ ๋ถํ๋ฅผ ์ผ์ผํค๋์ง ์ง์ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค
5. Tree ํํ์ ์คํ ๊ณํ ๋ถ์
1. -> Limit: 3 row(s) (cost=24.6 rows=3) (actual time=1.27..1.28 rows=3 loops=1)
2. -> Nested loop inner join (cost=24.6 rows=20) (actual time=1.27..1.28 rows=3 loops=1)
3. -> Sort: l.created_at DESC (cost=17.6 rows=20) (actual time=1.24..1.24 rows=3 loops=1)
4. -> Filter: ((l.published = true) and (l.created_at between '2024-10-01 00:00:18.000000' and '2024-11-01 00:00:18.000000')) (cost=17.6 rows=20) (actual time=1.19..1.21 rows=17 loops=1)
5. -> Index lookup on l using FK9tgknmmyr2kafs9bvfw5k9n84 (user_id=uuid_to_bin('95c2eeac-62fe-4d8e-9cb5-5f05be6d7df7')), with index condition: (l.user_id = <cache>(uuid_to_bin('95c2eeac-62fe-4d8e-9cb5-5f05be6d7df7'))) (cost=17.6 rows=20) (actual time=1.17..1.18 rows=20 loops=1)
6. -> Single-row covering index lookup on r using UK6ln872eudt3ku5rk8vlj43f0r (letter_id=l.letter_id) (cost=1.02 rows=1) (actual time=0.0117..0.0117 rows=1 loops=3)
explain analyze ์ TREE ํฌ๋งท์ ์คํ ์์๋ ๋ค์ ๊ธฐ์ค์ผ๋ก ์ฝ์ต๋๋ค.
- ๋ค์ฌ์ฐ๊ธฐ๊ฐ ๊ฐ์ ๋ ๋ฒจ์์๋ ์๋จ์ ์์นํ ๋ผ์ธ์ด ๋จผ์ ์คํ
- ๋ค์ฌ์ฐ๊ธฐ๊ฐ ๋ค๋ฅธ ๋ ๋ฒจ์์๋ ๊ฐ์ฅ ์์ชฝ์ ์์นํ ๋ผ์ธ์ด ๋จผ์ ์คํ
๋ฐ๋ผ์, ์ ์คํ ๊ณํ์ 5 → 4 → 3 → 6 → 2 → 1 ์์๋ก ์คํ๋ฉ๋๋ค.
โถ Tree ํฌ๋งท์ ์ฃผ์ ์งํ ์ค๋ช
actual time / rows / loops ์ ๋ํ ๊ฐ๋ ์ 6๋ฒ ๋ผ์ธ๊ณผ ํจ๊ป ์์๋ณด๊ฒ ์ต๋๋ค.
actual time (์ค์ ์์๋ ์๊ฐ, ms)
- actual time=0.0117..0.0117 ์์ ์ฒซ ๋ฒ์งธ ๊ฐ(0.0117ms)์ ์ฒซ ๋ฒ์งธ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ ๊ฑธ๋ฆฐ ํ๊ท ์๊ฐ, ๋ ๋ฒ์งธ ๊ฐ(0.0117ms)์ ๋ง์ง๋ง ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ ๊ฑธ๋ฆฐ ํ๊ท ์๊ฐ์ ๋๋ค.
rows (์ฒ๋ฆฌํ ๋ ์ฝ๋ ๊ฑด์)
- rows=1 ์ ํด๋น ๋ผ์ธ์ ์คํํ๊ณ ์ฒ๋ฆฌํ ํ ์ด๋ธ์ ํ๊ท ๋ ์ฝ๋ ๊ฑด์
loops (๋ฐ๋ณต ํ์)
- ํ ์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์ฐพ๋ ์์ ์ด ๋ฐ๋ณต๋ ํ์์ ๋๋ค. letter_id=l.letter_id ๋ฅผ ํตํด ๋ ์ฝ๋๋ฅผ ์ฐพ๋ ์์ ์ด 3๋ฒ ๋ฐ๋ณต๋์์ต๋๋ค.
์ฌ๊ธฐ์ actual time๊ณผ rows๋ฅผ ํ๊ท ์๊ฐ๊ณผ ํ๊ท ๋ ์ฝ๋ ์๋ก ์ค๋ช ํ ์ด์ ๋ loops ๊ฐ์ด 1 ์ด์์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋ฅผ ๋ค์ด, reply ํ ์ด๋ธ์์ l.letter_id์ ์ผ์นํ๋ ๋ ์ฝ๋๋ฅผ ์ฐพ๋ ์์ ์ด ์ด 3๋ฒ ๋ฐ๋ณต๋์๊ณ , ๋งค๋ฒ ์ฒซ ๋ฒ์งธ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ํ๊ท 0.0117ms๊ฐ ์์๋์์ผ๋ฉฐ, ๋ง์ง๋ง ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ๋ ํ๊ท 0.0117ms๊ฐ ๊ฑธ๋ฆฐ ๊ฒ์ ๋๋ค.
๋ฐ๋ผ์, ๋ฐ๋ณต ์คํ(loops)์ด ์์ ๋๋ actual time๊ณผ rows ๊ฐ์ด ๊ฐ ๋ฐ๋ณต์ ํ๊ท ์ ๋ํ๋ธ๋ค๋ ์ ์ ์ดํดํด์ผ ํฉ๋๋ค.
โถ Tree ํฌ๋งท์์ Using filesort ๋ถ์
์ด์ ์คํ ๊ณํ์ 3๋ฒ ๋ผ์ธ์์ Using filesort ๊ฐ ๋ฐ์ํ ๋ถ๋ถ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Sort: l.created_at DESC (cost=12.1 rows=17) (actual time=0.349..0.35 rows=11 loops=1)
ํด๋น ๋ผ์ธ์ ๋ณด๋ ์ ๋ ฌํ๋๋ฐ 0.3ms ๊ฐ ๊ฑธ๋ ธ์ต๋๋ค. ๋ง์ ๋ถํ๊ฐ ๋ฐ์ํ์ง ์์๋๋ฐ์. ๊ทธ ์์ธ์ ๋ํด ๋ถ์ํด๋ดค์ต๋๋ค.
์ฟผ๋ฆฌ์ ORDER BY ๊ฐ ์ฌ์ฉ๋๋ฉด ๋ฐ๋์ 3๊ฐ์ง ์ฒ๋ฆฌ ๋ฐฉ๋ฒ ์ค ํ๋๋ก ์ ๋ ฌ๋ฉ๋๋ค.
- ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ๋ ฌ → Extra ๋ณ๋ ํ๊ธฐ ์์
- ๋ฐ๋์ ORDER BY์ ๋ช ์๋ ์ปฌ๋ผ์ด ์ ์ผ ๋จผ์ ์ฝ๋ ํ ์ด๋ธ์ ์ํ๊ณ , ORDER BY ์์๋๋ก ์์ฑ๋ ์ธ๋ฑ์ค๊ฐ ์์ด์ผ ํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ๋ก ์ฝ๋ ํ ์ด๋ธ์ ์ปฌ๋ผ์ ๋ํ WHERE ์กฐ๊ฑด์ด ์๋ค๋ฉด, ๊ทธ ์กฐ๊ฑด๊ณผ ORDER BY๋ ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- B-Tree ๊ณ์ด์ด ์๋ R-Tree(๊ณต๊ฐ ์ธ๋ฑ์ค) / ์ ๋ฌธ ๊ฒ์ ์ธ๋ฑ์ค / ํด์ ์ธ๋ฑ์ค์์๋ ์ด ๋ฐฉ๋ฒ ์ฌ์ฉ ๋ถ๊ฐํฉ๋๋ค.
- ์กฐ์ธ์์ ๋๋ผ์ด๋น ํ
์ด๋ธ๋ง ์ ๋ ฌ → Using filesort
- '์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ ๋ ฌ'์ ์ฐจ์ ์ฑ ์ผ๋ก ์กฐ์ธ์์ ์ฒซ ๋ฒ์งธ๋ก ์ฝํ๋ ํ ์ด๋ธ์ ์นผ๋ผ๋ง์ผ๋ก ORDER BY ์ ์ ์์ฑํด์ผ ํฉ๋๋ค.
- ์กฐ์ธ์์ ์กฐ์ธ ๊ฒฐ๊ณผ๋ฅผ ์์ ํ
์ด๋ธ๋ก ์ ์ฅ ํ ์ ๋ ฌ → Using temporary; Using filesort ๊ฐ ํ์
- ์ ๋ ฌํด์ผ ํ๋ ๋ ์ฝ๋ ๊ฑด์๊ฐ ๊ฐ์ฅ ๋ง๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ๋๋ฆฐ ์ ๋ ฌ ๋ฐฉ๋ฒ์ ๋๋ค.
- Using temporary; ๋ ๋ฉ๋ชจ๋ฆฌ๋ ๋์คํฌ์์ ์์ํ ์ด๋ธ์ ์ฌ์ฉํด์ ์ ๋ ฌ์ ์ํํ ๋ ๋ํ๋ฉ๋๋ค.
์ฌ๊ธฐ์, ์ ๋ 2๋ฒ์งธ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ธ '์กฐ์ธ์์ ๋๋ผ์ด๋น ํ ์ด๋ธ๋ง ์ ๋ ฌ' ์ด ์ ์ฉ๋์์ต๋๋ค. ๋คํํ ์ต์ ์ ์ ๋ ฌ ๋ฐฉ๋ฒ์ ์๋์์ต๋๋ค. ํ์ง๋ง, ๋๋ผ์ด๋น ํ ์ด๋ธ์ ๊ฒฐ๊ณผ๊ฐ ๋ง๋ค๋ฉด ์ ๋ ฌํ๋๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ๊ฒ์ด๊ธฐ ๋๋ฌธ์ EXPLAIN ANALYZE ๋ก ์ค์ ์ฟผ๋ฆฌ์ ์คํ ์๊ฐ์ ํ์ ํ๋ ๊ฒ์ด ์ค์ํ๋ค ์๊ฐํฉ๋๋ค.
6. ๊ฒฐ๋ก : ์คํ ๊ณํ์์ ๋ฌด์์ ์ด๋ป๊ฒ ์ฝ์ด์ผ ํ๋๊ฐ?
์ด๋ฒ ๊ธ์์๋ ์คํ ๊ณํ์ ์ฝ๋ ๋ฐฉ๋ฒ๊ณผ ์ค์ ์ฟผ๋ฆฌ ์คํ ๊ฒฐ๊ณผ๋ฅผ ํด์ํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
๊ฐ๋จํ ์์ฝํ์๋ฉด, EXPLAIN์์ ํ์ธํ ์ฃผ์ ์ปฌ๋ผ์
- key ์ key_len ์ ํตํด ์๋๋ ์ธ๋ฑ์ค๊ฐ ์ฐ์ด๋์ง
- type ์ ํตํด ์ธ๋ฑ์ค๊ฐ ์ด๋ป๊ฒ ์ฐ์ด๋์ง
- rows ์ filtered ๋ฅผ ํตํด ๋ถํ์ํ ํ์ ๋ง์ด ์ฝ์ง๋ ์๋์ง
- Extra ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ฟผ๋ฆฌ์ ์ถ๊ฐ์ ์ธ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ์ง
EXPLAIN ANALYZE ์ Tree ํํ์ ์คํ ๊ณํ์ ํตํด ์ค์ ์ฟผ๋ฆฌ๊ฐ ์ด๋ ๋ถ๋ถ์์ ์ฑ๋ฅ์ด ์๋์ค๋์ง ํ์ธํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ์ธ์ ์ธ๋ฑ์ค๋ฅผ ์์ ํ๊ณ ์ฟผ๋ฆฌ๋ฅผ ํ๋ํด์ผ ํ๋์ง์ ๋ํด ๋ค์๊ณผ ๊ฐ์ด ์ ๋ฆฌํ ์ ์์ต๋๋ค.
- type ๊ฐ์ด ALL(ํ ์ด๋ธ ํ ์ค์บ) ์ผ๋. (index - ์ธ๋ฑ์ค ํ ์ค์บ์ผ ๊ฒฝ์ฐ๋ ๊ณ ๋ ค)
- rows ๊ฐ์ด ํฌ๊ณ , filtered ๊ฐ์ด ๋ฎ์ ๋ (๋ถํ์ํ๊ฒ ๋ง์ ํ์ ์คํ ๋ฆฌ์ง ์์ง์ด ์ฝ์ ๊ฒ)
- Extra ๊ฐ์ด Using temporary; Using filesort; ํจ๊ป ๋ฑ์ฅํ๋ฉด ์ฟผ๋ฆฌ์ ๋ถํ๊ฐ ๋๋ค. ๋ง์ฝ, Using filesort ๋ง ๋์จ๋ค๋ฉด ์ค์ ์คํ ์๊ฐ์ ๋ณด๊ธฐ.
์ถ๊ฐ์ ์ผ๋ก ์ฟผ๋ฆฌ ํ๋์๋ ๋ค์ํ ๊ฒฝ์ฐ๊ฐ ์กด์ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, Nested Loop Join์ด ๋ฐ๋ณต๋๋ ์ํฉ์์๋ Hash Join์ ์ฌ์ฉํ๋๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ ํ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
๊ทธ๋ฌ๋, ์คํ ๊ณํ์ ์ ํํ ์ฝ์ ์ ์๋ ๊ฒ์ด ์ฟผ๋ฆฌ ์ต์ ํ์ ์ ์ ์กฐ๊ฑด์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์คํ ๊ณํ์ ํด์ํ์ง ๋ชปํ ์ํ์์ ์ธ๋ฑ์ค๋ฅผ ๋ฌด์์ ์ถ๊ฐํ๊ฑฐ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ ํ๋ ๊ฒ์ ์คํ๋ ค ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ ํ์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ง์ง๋ง์ผ๋ก, Extra ์ปฌ๋ผ์ ๋งค์ฐ ๋ค์ํ ๊ฐ์ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๊ฐ์ ๋ฏธ๋ฆฌ ์ธ์ฐ๊ธฐ๋ณด๋ค๋ ์์ฃผ ๋ฑ์ฅํ๋ ๊ฐ๋ค์ ์ฐ์ ์ ์ผ๋ก ํ์ตํ๊ณ , ํ์ํ ๋๋ง๋ค ์๋ก์ด ๊ฐ์ ์ฐพ์์ ์ตํ๋ ๋ฐฉ์์ด ๋ ํจ์จ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด๋ฒ ๊ฒฝํ์ผ๋ก ์คํ ๊ณํ์ ์ด๋ก ์ ์ผ๋ก ์๋ ๊ฒ์ด ์๋๋ผ ์ค์ ์ ์ฉํด๋ณด๋ฉด์ ์คํ ๊ณํ์์ ๋ฌด์์ ๋ด์ผ ํ๋์ง, ์ด๋ป๊ฒ ๋ด์ผ ํ๋์ง ์ ๋ฆฌํ ์ ์๋ ๊ฒฝํ์ด์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ๊ฑธ์์ ๋, ์ธ๋ฑ์ค๊ฐ ํจ์จ์ ์ธ์ง ํ๋จํ ์ ์๋ ๋์ ๊ฐ์ง๊ฒ ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค. ํ์ง๋ง, ์ฟผ๋ฆฌ ์ฑ๋ฅ ๊ฐ์ ์ ์ธ๋ฑ์ค ์ถ๊ฐ๊ฐ ์๋ ์ฟผ๋ฆฌ๋ฅผ ์์ ํ๋ ๊ฒ๋ง์ผ๋ก ํด๊ฒฐ๋๋ ๊ฒฝ์ฐ๋ ์๊ธฐ ๋๋ฌธ์ ์์ผ๋ก 9์ฅ๊ณผ 11์ฅ์ ๋์ค๋ ๋ค์ํ ์ต์ ํ ๊ธฐ๋ฒ์ ํ์ตํ๋ฉฐ, ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ์ง ์๊ณ ๋ ์ฟผ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ํ๋ํ๋ ๋ฐฉ๋ฒ์ ์ตํ๋ณด๊ณ ์ ํฉ๋๋ค. ์ด๋ฌํ ๊ณผ์ ์ ํตํด ์ฟผ๋ฆฌ ์ต์ ํ ์ญ๋์ ๋์ฑ ๊ฐํํ ์ ์๋๋ก, ์์ผ๋ก๋ ๊พธ์คํ ๊ณต๋ถํ๊ณ ์ ๋ฆฌํด ๋๊ฐ๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
์ถ์ฒ
- MySQL (MariaDB) ์ธ๋ฑ์ค ์ปจ๋์ ํธ์๋ค์ด
- 10.์คํ๊ณํ ไธญ Real MySQL 8.0 1๊ถ
- Line ๊ธฐ์ ๋ธ๋ก๊ทธ MySQL Workbench์ VISUAL EXPLAIN์ผ๋ก ์ธ๋ฑ์ค ๋์ ํ์ธํ๊ธฐ