๐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋: ์ฟผ๋ฆฌ ์ต์ ํ์ ๋์ ์ด๋์ผ๊น? ๐

์๋ ํ์ธ์, ์ฌ๋ฌ๋ถ! ์ค๋์ ์ ๋ง ํฅ๋ฏธ์ง์งํ ์ฃผ์ ๋ก ์ฐพ์์์ด์. ๋ฐ๋ก "๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋"๊ณผ "์ฟผ๋ฆฌ ์ต์ ํ"์ ๋ํด ๊น์ด ํํค์ณ๋ณผ ๊ฑฐ์์. ์ด ์ฃผ์ , ์ด๋ป๊ฒ ๋ณด๋ฉด ์ข ๋ฑ๋ฑํ๊ณ ์ง๋ฃจํ ์ ์๊ฒ ์ง๋ง, ์ ๊ฐ ์ฌ๋ฏธ์๊ฒ ํ์ด๋ณผ๊ฒ์! ใ ใ ใ
์ฌ๋ฌ๋ถ, ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ญ์ง ์์๋์? ์ฝ๊ฒ ๋งํด์ ์์ฒญ๋๊ฒ ํฐ ๋์งํธ ์ฐฝ๊ณ ๋ผ๊ณ ์๊ฐํ๋ฉด ๋ผ์. ์ด ์ฐฝ๊ณ ์๋ ์ฐ๋ฆฌ๊ฐ ํ์ํ ๋ชจ๋ ์ ๋ณด๊ฐ ๊น๋ํ๊ฒ ์ ๋ฆฌ๋์ด ์์ฃ . ๊ทผ๋ฐ ๋ฌธ์ ๋ ์ด ์ฐฝ๊ณ ๊ฐ ๋๋ฌด ์ปค์ ์ํ๋ ๋ฌผ๊ฑด์ ์ฐพ๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ์ ์๋ค๋ ๊ฑฐ์์. ์ฌ๊ธฐ์ ๋ฑ์ฅํ๋ ๊ฒ ๋ฐ๋ก "์ฟผ๋ฆฌ ์ต์ ํ"๋๋๋ค! ๐ต๏ธโโ๏ธ
์ฟผ๋ฆฌ ์ต์ ํ๋ ๋ง์น ์ด ๊ฑฐ๋ํ ์ฐฝ๊ณ ์์ ๊ฐ์ฅ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ๋ฌผ๊ฑด์ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์ฐ๊ตฌํ๋ ๊ฑฐ์์. ์ฐ๋ฆฌ๊ฐ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์ ์ฌ์ฉํ ๋, ๋น ๋ฅด๊ฒ ์ํ๋ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒ๋ ๋ค ์ด๋ฐ ์ต์ ํ ๋๋ถ์ด์์!
๐ค ๊ถ๊ธํด์! ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ด ์ ์ค์ํ ๊น์?
- ์ฌ์ฉ์ ๊ฒฝํ ํฅ์: ๋น ๋ฅธ ์๋ต ์๊ฐ = ํ๋ณตํ ์ฌ์ฉ์ ๐
- ์๋ฒ ์์ ์ ์ฝ: ํจ์จ์ ์ธ ์ฟผ๋ฆฌ = ๋น์ฉ ์ ๊ฐ ๐ฐ
- ํ์ฅ์ฑ ๊ฐ์ : ์ต์ ํ๋ DB = ๋ ๋ง์ ์ฌ์ฉ์ ์์ฉ ๊ฐ๋ฅ ๐
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ์ธ๊ณ๋ก ๋ค์ด๊ฐ๋ณผ๊น์? ์ค๋น๋์ จ๋์? ๊ทธ๋ผ ๊ณ ๊ณ ์ฝ~! ๐โโ๏ธ๐จ
๐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๊ธฐ์ด: ์ ํ์ํ ๊น์?
์ฌ๋ฌ๋ถ, ํน์ ๋๋ฆฐ ์น์ฌ์ดํธ๋ ์ฑ์ ์ฌ์ฉํด๋ณธ ์ ์๋์? ์ง์ฆ ๋์ฃ , ๊ทธ์ตธ? ใ ใ ใ ๊ทธ๋ฐ๋ฐ ๋ง์ด์์, ์ด๋ฐ ๋๋ฆฐ ๋ฐ์ ์๋์ ์ฃผ๋ฒ์ด ๋ฐ๋ก ์ต์ ํ๋์ง ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ผ ์ ์์ด์!
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋ง์น ์๋์ฐจ ์์ง์ ํ๋ํ๋ ๊ฒ๊ณผ ๋น์ทํด์. ๋ ๋น ๋ฅด๊ณ , ๋ ํจ์จ์ ์ผ๋ก ๋ง๋๋ ๊ฑฐ์ฃ !
์๋ฅผ ๋ค์ด๋ณผ๊น์? ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ์ฌ์ฉ์๊ฐ "ํ๋ก๊ทธ๋๋ฐ ๊ฐ์ฌ"๋ฅผ ๊ฒ์ํ๋ค๊ณ ํด๋ด์. ์ด ๊ฐ๋จํ ๊ฒ์์ด ์๋ฐฑ๋ง ๊ฐ์ ๋ฐ์ดํฐ ์ค์์ ์ ์ ํ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์๋ด์ผ ํ๋ ๊ฑฐ์์. ๋ง์ฝ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ต์ ํ๋์ด ์์ง ์๋ค๋ฉด, ์ด ๊ฒ์์ ๋ช ์ด, ์ฌ์ง์ด ๋ช ๋ถ์ด ๊ฑธ๋ฆด ์๋ ์์ด์! ๐ฑ
๐ก ์๊ณ ๊ณ์ จ๋์?
Amazon.com์ ์ฐ๊ตฌ์ ๋ฐ๋ฅด๋ฉด, ํ์ด์ง ๋ก๋ฉ ์๊ฐ์ด 100ms๋ง ๋์ด๋๋ ๋งค์ถ์ด 1% ๊ฐ์ํ๋ค๊ณ ํด์. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฑ๋ฅ์ด ๋น์ฆ๋์ค์ ์ผ๋ง๋ ์ค์ํ์ง ์ ์ ์์ฃ !
๊ทธ๋์ ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ๋ํด์ผ ํด์. ์ด๊ฒ ๋ฐ๋ก ์ฟผ๋ฆฌ ์ต์ ํ์ ์์์ ์ด์์. ์ฟผ๋ฆฌ๋ ๋ญ๋๊ณ ์? ์ฝ๊ฒ ๋งํด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณด๋ด๋ "์์ฒญ"์ด์์. "์ผ, DB์ผ! ํ๋ก๊ทธ๋๋ฐ ๊ฐ์ฌ ์ข ์ฐพ์์ค!"๋ผ๊ณ ํ๋ ๊ฑฐ์ฃ . ใ ใ ใ
์ฟผ๋ฆฌ ์ต์ ํ๋ ์ด "์์ฒญ"์ ๊ฐ์ฅ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ๋ง๋๋ ๊ณผ์ ์ด์์. ๋ง์น ํ๋ฐฐ ๊ธฐ์ฌ๋์ด ๊ฐ์ฅ ๋น ๋ฅธ ๊ฒฝ๋ก๋ก ํ๋ฐฐ๋ฅผ ๋ฐฐ๋ฌํ๋ ๊ฒ์ฒ๋ผ์!
์ด ๊ทธ๋ฆผ์ ๋ณด์ธ์. ์ผ์ชฝ์ ํ๋ ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์. ํฐ ์์ ๋๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ๋ํ๋ด์ฃ . ์ค๋ฅธ์ชฝ์ ํ๋ ํ์ ๋ชจ์ต์ด์์. ์ฟผ๋ฆฌ๊ฐ ํจ์ฌ ์๊ณ ๋นจ๋ผ์ก์ฃ ? ์ด๊ฒ ๋ฐ๋ก ์ฐ๋ฆฌ๊ฐ ์ถ๊ตฌํ๋ ๊ฑฐ์์!
์, ์ด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ด ์ ์ค์ํ์ง ๊ฐ์ด ์ค์๋์? ๋ค์ ์น์ ์์๋ ์ค์ ๋ก ์ด๋ป๊ฒ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ๋์ง ์์ธํ ์์๋ณผ ๊ฑฐ์์. ์ฌ๋ฏธ์์ ๊ฑฐ์์, ๊ธฐ๋ํ์ธ์! ๐
๐ ์ฟผ๋ฆฌ ์ต์ ํ์ ๊ธฐ๋ณธ ์์น
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฟผ๋ฆฌ ์ต์ ํ์ ์ธ๊ณ๋ก ๋ค์ด๊ฐ๋ณผ๊น์? ๊ฑฑ์ ๋ง์ธ์, ์ด๋ ค์ด ์ฉ์ด๋ ์ต๋ํ ์ฝ๊ฒ ํ์ด์ ์ค๋ช ํด๋๋ฆด๊ฒ์. ๋ง์น ์น๊ตฌ์ ์๋ค ๋ ๋ ๊ฒ์ฒ๋ผ์! ใ ใ ใ
์ฟผ๋ฆฌ ์ต์ ํ์ ์ฒซ ๋ฒ์งธ ์์น์ ๋ฐ๋ก "ํ์ํ ๊ฒ๋ง ๊ฐ์ ธ์ค๊ธฐ"์์.
์ด๊ฒ ๋ฌด์จ ๋ง์ด๋๊ณ ์? ์... ์ด๋ ๊ฒ ์๊ฐํด๋ณด์ธ์. ์ฌ๋ฌ๋ถ์ด ํธ์์ ์ ์ฐ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ๋ค๊ณ ํด๋ด์. ๊ทผ๋ฐ ์ฐ์ ๋ง ์ฌ๋ ๊ฒ ์๋๋ผ ๊ฐ๊ฒ ์์ ๋ชจ๋ ๋ฌผ๊ฑด์ ๋ค ์ง์ด ๋ค๊ณ ๊ณ์ฐ๋๋ก ๊ฐ๋ฉด ์ด๋จ๊น์? ๋ฏธ์น ์ง์ด๊ฒ ์ฃ ? ใ ใ ใ
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ง์ฐฌ๊ฐ์ง์์. ํ์ํ ์ ๋ณด๋ง ์ ํํ๊ฒ ์์ฒญํ๋ ๊ฒ ์ค์ํด์. ์ด๊ฑธ SQL์์๋ ์ด๋ ๊ฒ ํํํด์:
-- ๋์ ์
SELECT * FROM users;
-- ์ข์ ์
SELECT name, email FROM users WHERE active = true;
์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ๋ชจ๋ ์ ๋ณด๋ฅผ ๋ค ๊ฐ์ ธ์ค๋ ๊ฑฐ์์. ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ํ์ํ ์ ๋ณด(์ด๋ฆ๊ณผ ์ด๋ฉ์ผ)๋ง ๊ฐ์ ธ์ค๊ณ , ๊ฒ๋ค๊ฐ ํ์ฑ ์ฌ์ฉ์๋ง ์ ํํ๊ณ ์์ฃ . ํจ์ฌ ํจ์จ์ ์ด๊ฒ ์ฃ ?
๐ ๊ฟํ!
SELECT * ๋ ํธ๋ฆฌํ์ง๋ง, ์ค์ ํ๋ก๋์ ํ๊ฒฝ์์๋ ๊ฐ๋ฅํ ํ ํผํ์ธ์. ํ์ํ ์ปฌ๋ผ๋ง ๋ช ์์ ์ผ๋ก ์ ํํ๋ ๊ฒ์ด ์ฑ๋ฅ์ ์ข๋ต๋๋ค!
๋ ๋ฒ์งธ ์์น์ "์ธ๋ฑ์ค๋ฅผ ์ ํ์ฉํ๊ธฐ"์์. ์ธ๋ฑ์ค๊ฐ ๋ญ๋๊ณ ์? ์ฑ ์ ๋ชฉ์ฐจ๋ผ๊ณ ์๊ฐํ๋ฉด ๋ผ์!
์ธ๋ฑ์ค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ ๋ณด๋ฅผ ๋นจ๋ฆฌ ์ฐพ์ ์ ์๊ฒ ๋์์ฃผ๋ ํน๋ณํ ๊ตฌ์กฐ์์.
์๋ฅผ ๋ค์ด, ์ฌ๋ฅ๋ท์์ "ํ๋ก๊ทธ๋๋ฐ" ์นดํ ๊ณ ๋ฆฌ์ ๋ชจ๋ ๊ฐ์๋ฅผ ์ฐพ๋๋ค๊ณ ํด๋ด์. ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ชจ๋ ๊ฐ์๋ฅผ ํ๋ํ๋ ๋ค ํ์ธํด์ผ ํด์. ๊ทผ๋ฐ "์นดํ ๊ณ ๋ฆฌ"์ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด? ํจ์ฌ ๋นจ๋ฆฌ ์ฐพ์ ์ ์๊ฒ ์ฃ !
-- ์ธ๋ฑ์ค ์์ฑ ์์
CREATE INDEX idx_category ON courses(category);
-- ์ด์ ์ด๋ฐ ์ฟผ๋ฆฌ๊ฐ ํจ์ฌ ๋นจ๋ผ์ง ๊ฑฐ์์
SELECT * FROM courses WHERE category = 'ํ๋ก๊ทธ๋๋ฐ';
ํ์ง๋ง ์ฃผ์ํ์ธ์! ์ธ๋ฑ์ค๊ฐ ๋ง๋ค๊ณ ๋ฌด์กฐ๊ฑด ์ข์ ๊ฑด ์๋์์. ์ธ๋ฑ์ค๋ ๊ด๋ฆฌ๊ฐ ํ์ํ๊ณ , ๋ฐ์ดํฐ ์ ๋ ฅ/์์ /์ญ์ ์ ์ถ๊ฐ ์์ ์ด ํ์ํ๊ฑฐ๋ ์. ๋ง์น ์ฑ ์ ๋ชฉ์ฐจ๋ฅผ ๊ณ์ ์ ๋ฐ์ดํธํด์ผ ํ๋ ๊ฒ์ฒ๋ผ์!
์ด ๊ทธ๋ํ๋ฅผ ๋ณด์ธ์. ๋นจ๊ฐ ์ ์ ์ธ๋ฑ์ค ์์ด ๊ฒ์ํ ๋์ ์๊ฐ์ด์์. ๋ฐ์ดํฐ๊ฐ ๋ง์์ง์๋ก ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋์ฃ . ๋ฐ๋ฉด ์ด๋ก ์ ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ ๋์์. ๋ฐ์ดํฐ๊ฐ ๋์ด๋๋ ๊ฒ์ ์๊ฐ์ด ํฌ๊ฒ ์ฆ๊ฐํ์ง ์์์. coolํ์ฃ ? ๐
์ธ ๋ฒ์งธ ์์น์ "์กฐ์ธ(JOIN)์ ํ๋ช ํ๊ฒ ์ฌ์ฉํ๊ธฐ"์์. ์กฐ์ธ์ ์ฌ๋ฌ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ํฉ์น๋ ์์ ์ด์์. ๊ทผ๋ฐ ์ด๊ฒ ์๋ชป๋๋ฉด ์ฑ๋ฅ์ ์์ฒญ๋ ์ ์ํฅ์ ์ค ์ ์์ด์!
๋ณต์กํ ์กฐ์ธ์ ๋ง์น ์ฌ๋ฌ ๊ฐ์ ํผ์ฆ์ ํ ๋ฒ์ ๋ง์ถ๋ ๊ฒ๊ณผ ๊ฐ์์. ์ด๋ ต๊ณ ์๊ฐ๋ ์ค๋ ๊ฑธ๋ฆฌ์ฃ !
์๋ฅผ ๋ค์ด, ์ฌ๋ฅ๋ท์์ ํน์ ๊ฐ์ฌ์ ๋ชจ๋ ๊ฐ์์ ์๊ฐ์ ์ ๋ณด๋ฅผ ํ ๋ฒ์ ๊ฐ์ ธ์ค๋ ค๋ฉด ์ด๋ ๊ฒ ํ ์ ์์ด์:
SELECT c.title, u.name
FROM courses c
JOIN enrollments e ON c.id = e.course_id
JOIN users u ON e.user_id = u.id
WHERE c.instructor_id = 123;
์ด ์ฟผ๋ฆฌ๋ ์ธ ๊ฐ์ ํ ์ด๋ธ(courses, enrollments, users)์ ์กฐ์ธํ๊ณ ์์ด์. ๋ฐ์ดํฐ๊ฐ ๋ง์์ง๋ฉด ์ด๋ฐ ์ฟผ๋ฆฌ๋ ์์ฒญ ๋๋ ค์ง ์ ์์ด์. ๊ทธ๋์ ๊ฐ๋ฅํ๋ฉด ์กฐ์ธ์ ์ค์ด๊ณ , ๊ผญ ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๋ ๊ฒ ์ข์์.
โ ๏ธ ์ฃผ์!
๋๋ฌด ๋ง์ ํ ์ด๋ธ์ ํ ๋ฒ์ ์กฐ์ธํ๋ฉด ์ฟผ๋ฆฌ ์ฑ๋ฅ์ด ๊ธ๊ฒฉํ ๋จ์ด์ง ์ ์์ด์. ๊ฐ๋ฅํ๋ฉด 3-4๊ฐ ์ดํ๋ก ์ ์งํ๋ ๊ฒ ์ข๋ต๋๋ค!
์, ์ฌ๊ธฐ๊น์ง๊ฐ ์ฟผ๋ฆฌ ์ต์ ํ์ ๊ธฐ๋ณธ ์์น์ด์์. ์ด๋์? ์๊ฐ๋ณด๋ค ๋ณ๊ฑฐ ์๋์ฃ ? ใ ใ ใ ํ์ง๋ง ์ด ๊ฐ๋จํ ์์น๋ค๋ง ์ ์ง์ผ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฑ๋ฅ์ด ํ ์ข์์ง ๊ฑฐ์์!
๋ค์ ์น์ ์์๋ ์ด๋ฐ ์์น๋ค์ ์ค์ ๋ก ์ด๋ป๊ฒ ์ ์ฉํ๋์ง, ๊ทธ๋ฆฌ๊ณ ๋ ๊ณ ๊ธ ๊ธฐ์ ๋ค์ ๋ญ๊ฐ ์๋์ง ์์๋ณผ ๊ฑฐ์์. ๊ธฐ๋๋์ง ์๋์? ์ ๋ ๋๋ฌด ์ ๋์! ๐คฉ
๐ ๏ธ ์ค์ ์ฟผ๋ฆฌ ์ต์ ํ ํ ํฌ๋
์, ์ด์ ์ง์ง ์ค์ ์ผ๋ก ๋ค์ด๊ฐ๋ณผ๊น์? ์ฌ๋ฌ๋ถ, ๊ธด์ฅํ์ จ๋์? ๊ด์ฐฎ์์, ์ ๊ฐ ์น์ ํ๊ฒ ์ค๋ช ํด๋๋ฆด๊ฒ์. ๋ง์น ๋ง์๋ ๋ ์ํผ๋ฅผ ์๋ ค์ฃผ๋ฏ์ด์! ๐
์ฒซ ๋ฒ์งธ ํ ํฌ๋: ์๋ธ์ฟผ๋ฆฌ ์ต์ ํํ๊ธฐ
์๋ธ์ฟผ๋ฆฌ๋ ๋ญ๊น์? ์ฟผ๋ฆฌ ์์ ๋ ๋ค๋ฅธ ์ฟผ๋ฆฌ๊ฐ ์๋ ๊ฑฐ์์. ๋ง์น ์ธ์ ์ ์ํ์ฒ๋ผ ๊ฟ ์์ ๊ฟ์ด์ฃ ! ใ ใ ใ ๊ทผ๋ฐ ์ด ์๋ธ์ฟผ๋ฆฌ, ์๋ชป ์ฐ๋ฉด ์ฑ๋ฅ์ ์์ฒญ ๋จ์ด๋จ๋ฆด ์ ์์ด์.
์๋ฅผ ๋ค์ด๋ณผ๊น์? ์ฌ๋ฅ๋ท์์ ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๊ฐ์๋ฅผ ์ฐพ๋๋ค๊ณ ํด๋ด์:
-- ๋นํจ์จ์ ์ธ ์๋ธ์ฟผ๋ฆฌ
SELECT title
FROM courses
WHERE id = (
SELECT course_id
FROM enrollments
GROUP BY course_id
ORDER BY COUNT(*) DESC
LIMIT 1
);
-- ์ต์ ํ๋ ๋ฒ์
SELECT c.title
FROM courses c
JOIN (
SELECT course_id, COUNT(*) as enrollment_count
FROM enrollments
GROUP BY course_id
ORDER BY enrollment_count DESC
LIMIT 1
) e ON c.id = e.course_id;
๋ ๋ฒ์งธ ์ฟผ๋ฆฌ๊ฐ ๋ ํจ์จ์ ์ด์์. ์๋๊ณ ์? ์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ๋ฉ์ธ ์ฟผ๋ฆฌ์ ์๋ธ์ฟผ๋ฆฌ๊ฐ ๊ฐ๊ฐ ๋ฐ๋ก ์คํ๋์ง๋ง, ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ์กฐ์ธ์ ์ฌ์ฉํด์ ํ ๋ฒ์ ์ฒ๋ฆฌํ๊ฑฐ๋ ์!
๐ก ๊ฟํ!
๊ฐ๋ฅํ๋ฉด ์๋ธ์ฟผ๋ฆฌ๋ณด๋ค๋ ์กฐ์ธ์ ์ฌ์ฉํ์ธ์. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์กฐ์ธ์ด ๋ ๋น ๋ฅด๋ต๋๋ค!
๋ ๋ฒ์งธ ํ ํฌ๋: ํ์ด์ง๋ค์ด์ ์ต์ ํํ๊ธฐ
ํ์ด์ง๋ค์ด์ ์ด ๋ญ๋๊ณ ์? ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ฌ๋ฌ ํ์ด์ง๋ก ๋๋๋ ๊ฑฐ์์. ์ฌ๋ฅ๋ท์์ ๊ฐ์๋ฅผ ๊ฒ์ํ๋ฉด ํ ํ์ด์ง์ ๋ค ๋ณด์ฌ์ฃผ์ง ์๊ณ ์ฌ๋ฌ ํ์ด์ง๋ก ๋๋์์์? ๊ทธ๊ฒ ๋ฐ๋ก ํ์ด์ง๋ค์ด์ ์ด์์!
๊ทผ๋ฐ ์ด ํ์ด์ง๋ค์ด์ , ์๋ชปํ๋ฉด ์์ฒญ ๋๋ ค์ง ์ ์์ด์. ํนํ ๋ฐ์ดํฐ๊ฐ ๋ง์ ๋์. ์ด๋ป๊ฒ ์ต์ ํํ ์ ์์๊น์?
-- ๋นํจ์จ์ ์ธ ํ์ด์ง๋ค์ด์
SELECT *
FROM courses
ORDER BY created_at DESC
LIMIT 20 OFFSET 10000;
-- ์ต์ ํ๋ ํ์ด์ง๋ค์ด์
SELECT c.*
FROM courses c
JOIN (
SELECT id
FROM courses
ORDER BY created_at DESC
LIMIT 20 OFFSET 10000
) sub ON c.id = sub.id;
์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ 10,000๊ฐ์ ํ์ ๊ฑด๋๋ฐ๊ณ ๊ทธ ๋ค์ 20๊ฐ๋ฅผ ๊ฐ์ ธ์์. ๋ฐ์ดํฐ๊ฐ ๋ง์ผ๋ฉด ์ด๊ฒ ์์ฒญ ๋๋ ค์ ธ์. ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ๋จผ์ ํ์ํ ID๋ง ๊ฐ์ ธ์ค๊ณ , ๊ทธ ๋ค์์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํด์ ๊ฐ์ ธ์ค์ฃ . ํจ์ฌ ๋น ๋ฅด๋ต๋๋ค!
์ด ๊ทธ๋ํ๋ฅผ ๋ณด์ธ์. ๋นจ๊ฐ ์ ์ ์ต์ ํ ์ , ์ด๋ก ์ ์ ์ต์ ํ ํ์์. ํ์ด์ง ๋ฒํธ๊ฐ ๋์ด๋ ์๋ก ์ต์ ํ ์ ์ฟผ๋ฆฌ๋ ๋ก๋ฉ ์๊ฐ์ด ๊ธ๊ฒฉํ ์ฆ๊ฐํ์ง๋ง, ์ต์ ํ ํ์๋ ๊ฑฐ์ ์ผ์ ํ๊ฒ ์ ์ง๋์ฃ . ๋ฉ์ง์ง ์๋์? ๐
์ธ ๋ฒ์งธ ํ ํฌ๋: ์ธ๋ฑ์ค ํ๋ํ๊ธฐ
์์ ์ธ๋ฑ์ค๊ฐ ์ค์ํ๋ค๊ณ ํ์ฃ ? ๊ทผ๋ฐ ์ธ๋ฑ์ค๋ ์ ๋ง๋ค์ด์ผ ํด์. ๋ฌด์กฐ๊ฑด ๋ง์ด ๋ง๋ ๋ค๊ณ ์ข์ ๊ฒ ์๋์์!
์๋ฅผ ๋ค์ด, ์ฌ๋ฅ๋ท์์ ์ฌ์ฉ์๋ค์ด ์ฃผ๋ก ์นดํ ๊ณ ๋ฆฌ์ ๊ฐ๊ฒฉ์ผ๋ก ๊ฐ์๋ฅผ ๊ฒ์ํ๋ค๊ณ ํด๋ด์. ๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค ์ ์์ด์:
-- ๋ณตํฉ ์ธ๋ฑ์ค ์์ฑ
CREATE INDEX idx_category_price ON courses(category, price);
-- ์ด์ ์ด๋ฐ ์ฟผ๋ฆฌ๊ฐ ๋นจ๋ผ์ง ๊ฑฐ์์
SELECT * FROM courses WHERE category = 'ํ๋ก๊ทธ๋๋ฐ' AND price < 50000;
์ด๋ ๊ฒ ์์ฃผ ๊ฐ์ด ์ฌ์ฉ๋๋ ์ปฌ๋ผ๋ค์ ํ๋์ ์ธ๋ฑ์ค๋ก ๋ง๋๋ ๊ฑธ "๋ณตํฉ ์ธ๋ฑ์ค"๋ผ๊ณ ํด์. ์ด๊ฒ ๊ฐ๊ฐ ๋ฐ๋ก ์ธ๋ฑ์ค๋ฅผ ๋ง๋๋ ๊ฒ๋ณด๋ค ๋ ํจ์จ์ ์ผ ์ ์์ด์!
๐จ ์ฃผ์์ฌํญ!
์ธ๋ฑ์ค๊ฐ ๋ง์ผ๋ฉด INSERT, UPDATE, DELETE ์์ ์ด ๋๋ ค์ง ์ ์์ด์. ๊ผญ ํ์ํ ์ธ๋ฑ์ค๋ง ๋ง๋ค์ด์ผ ํด์!
๋ค ๋ฒ์งธ ํ ํฌ๋: ์ฟผ๋ฆฌ ์บ์ฑ ํ์ฉํ๊ธฐ
์บ์ฑ์ด ๋ญ๋๊ณ ์? ์ฝ๊ฒ ๋งํด์ "๊ธฐ์ตํด๋๊ธฐ"์์. ํ ๋ฒ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด๋๋ค๊ฐ ๋ค์์ ๊ฐ์ ์์ฒญ์ด ์ค๋ฉด ๋ฐ๋ก ์ฃผ๋ ๊ฑฐ์ฃ .
์๋ฅผ ๋ค์ด, ์ฌ๋ฅ๋ท์ "์ด๋ฒ ์ฃผ ์ธ๊ธฐ ๊ฐ์" ๋ชฉ๋ก์ ์๊ฐํด๋ด์. ์ด ๋ชฉ๋ก, ๋งค๋ฒ ์๋ก ๊ณ์ฐํ๋ ๊ฒ๋ณด๋ค ์ผ์ ์๊ฐ ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด๋๊ณ ์ฌ์ฌ์ฉํ๋ ๊ฒ ํจ์ฌ ํจ์จ์ ์ด๊ฒ ์ฃ ?
-- ์์ฌ ์ฝ๋ (์ค์ SQL์ด ์๋๋๋ค!)
IF (์บ์์ "์ด๋ฒ ์ฃผ ์ธ๊ธฐ ๊ฐ์" ์์ AND ์บ์๊ฐ ์ ์ ํจ) THEN
์บ์์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
ELSE
SQL๋ก ์๋ก ๊ณ์ฐํ๊ธฐ
๊ฒฐ๊ณผ๋ฅผ ์บ์์ ์ ์ฅํ๊ธฐ
END IF
์ด๋ ๊ฒ ํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ถํ๋ ์ค์ด๊ณ , ์๋ต ์๋๋ ๋นจ๋ผ์ง๊ณ ... ์ผ์์ด์กฐ์ฃ ! ๐
์, ์ฌ๊ธฐ๊น์ง๊ฐ ์ค์ ์ฟผ๋ฆฌ ์ต์ ํ ํ ํฌ๋์ด์์. ์ด๋์? ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์ฃ ? ใ ใ ใ ์ด๋ฐ ํ ํฌ๋๋ค์ ์ ํ์ฉํ๋ฉด ์ฌ๋ฌ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ด๊ณ ์์ผ๋ก ๋ณ์ ํ ๊ฑฐ์์! ๐
๋ค์ ์น์ ์์๋ ์ด๋ฐ ์ต์ ํ๋ฅผ ์ค์ ๋ก ์ด๋ป๊ฒ ์ธก์ ํ๊ณ ๋ชจ๋ํฐ๋งํ๋์ง ์์๋ณผ ๊ฑฐ์์. ๊ธฐ๋๋์ง ์๋์? ์ ๋ ๋๋ฌด ์ ๋์! ๐
๐ ์ฑ๋ฅ ์ธก์ ๊ณผ ๋ชจ๋ํฐ๋ง: ์ฐ๋ฆฌ์ ๋ ธ๋ ฅ์ด ํจ๊ณผ๊ฐ ์์์๊น?
์, ์ฌ๋ฌ๋ถ! ์ง๊ธ๊น์ง ์ด์ฌํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ๋ํ๊ณ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ์ด์. ๊ทผ๋ฐ ์ด๊ฒ ์ ๋ง ํจ๊ณผ๊ฐ ์๋์ง ์ด๋ป๊ฒ ์ ์ ์์๊น์? ๊ทธ๋ฅ "๋๋"์ผ๋ก๋ ์ ๋๊ฒ ์ฃ ? ใ ใ ใ ์ฐ๋ฆฌ์๊ฒ ๊ณผํ์ ์ธ ๋ฐฉ๋ฒ์ด ํ์ํด์!
์ฒซ ๋ฒ์งธ ๋จ๊ณ: ์ฟผ๋ฆฌ ์คํ ๊ณํ ๋ถ์ํ๊ธฐ
SQL์๋ ์์ฃผ ๋ฉ์ง ๊ธฐ๋ฅ์ด ์์ด์. ๋ฐ๋ก EXPLAIN์ด๋ผ๋ ๋ช ๋ น์ด์์. ์ด๊ฑธ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ์คํํ ๊ณํ์ธ์ง ์์ธํ ๋ณผ ์ ์์ด์. ๋ง์น ์๋ฆฌ์ฌ์ ๋ ์ํผ๋ฅผ ๋ค์ฌ๋ค๋ณด๋ ๊ฒ ๊ฐ์ฃ !
EXPLAIN SELECT * FROM courses WHERE category = 'ํ๋ก๊ทธ๋๋ฐ';
์ด ๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ด๋ฐ ์์ผ๋ก ๋๋ตํด์ค ๊ฑฐ์์:
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | courses | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 10.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
์ด๋จธ๋! ์ด๊ฒ ๋ญ์์? ๐ฑ ๊ฑฑ์ ๋ง์ธ์, ์ ๊ฐ ์ค๋ช ํด๋๋ฆด๊ฒ์.
- type: 'ALL'์ ์ ์ฒด ํ ์ด๋ธ ์ค์บ์ ์๋ฏธํด์. ๊ฐ์ฅ ๋นํจ์จ์ ์ด์ฃ .
- possible_keys: NULL์ด๋ผ๋ ๊ฑด ์ฌ์ฉ ๊ฐ๋ฅํ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ ๋ป์ด์์.
- rows: ์ฝ 1000๊ฐ์ ํ์ ๊ฒ์ฌํ ๊ฑฐ๋ผ๋ ๋ป์ด์์.
์ด๋ฐ ์ ๋ณด๋ฅผ ๋ณด๊ณ "์, ์ฌ๊ธฐ์ ์ธ๋ฑ์ค๊ฐ ํ์ํ๊ฒ ๊ตฌ๋!"๋ผ๊ณ ํ๋จํ ์ ์์ด์. ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ ํ ๋ค์ EXPLAIN์ ์คํํด๋ณด๋ฉด:
+----+-------------+---------+------------+------+---------------+-------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+-------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | courses | NULL | ref | idx_category | idx_category | 768 | const | 10 | 100.00 | Using index |
+----+-------------+---------+------------+------+---------------+-------------------+---------+-------+------+----------+-------------+
์์ฐ! ์์ ๋ฌ๋ผ์ก์ฃ ? ์ด์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด์ ๋จ 10๊ฐ์ ํ๋ง ๊ฒ์ฌํ๋ฉด ๋ผ์. ์์ฒญ๋ ๋ฐ์ ์ด์์! ๐
๐ก ํ๋ก ํ!
EXPLAIN ANALYZE๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์ ์คํ ์๊ฐ๊น์ง ๋ณผ ์ ์์ด์. ๋ ์์ธํ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ฃ !
๋ ๋ฒ์งธ ๋จ๊ณ: ์ฟผ๋ฆฌ ์คํ ์๊ฐ ์ธก์ ํ๊ธฐ
์คํ ๊ณํ์ ๋ถ์ํ๋ ๊ฒ๋ ์ข์ง๋ง, ์ค์ ๋ก ์ผ๋ง๋ ๋นจ๋ผ์ก๋์ง ์ง์ ์ธก์ ํด๋ณด๋ ๊ฒ๋ ์ค์ํด์. ๋๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ ์ฟผ๋ฆฌ ์คํ ์๊ฐ์ ์ธก์ ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํด์.
MySQL์ ์๋ก ๋ค๋ฉด:
SET profiling = 1;
SELECT * FROM courses WHERE category = 'ํ๋ก๊ทธ๋๋ฐ';
SHOW PROFILES;
์ด๋ ๊ฒ ํ๋ฉด ์ฟผ๋ฆฌ์ ์คํ ์๊ฐ์ ์ ํํ ์ ์ ์์ด์. ์ต์ ํ ์ ํ๋ฅผ ๋น๊ตํด๋ณด๋ฉด ์ผ๋ง๋ ๊ฐ์ ๋์๋์ง ํ๋์ ๋ณผ ์ ์์ฃ !
์ด ๊ทธ๋ํ๋ฅผ ๋ณด์ธ์. ์ต์ ํ๋ฅผ ๊ฑฐ๋ญํ ์๋ก ์คํ ์๊ฐ์ด ์ด๋ป๊ฒ ์ค์ด๋๋์ง ํ๋์ ๋ณผ ์ ์์ฃ ? ์ด๋ ๊ฒ ์๊ฐํํ๋ฉด ์ฐ๋ฆฌ์ ๋ ธ๋ ฅ์ด ์ผ๋ง๋ ํจ๊ณผ๊ฐ ์์๋์ง ์ฝ๊ฒ ์ ์ ์์ด์!
์ธ ๋ฒ์งธ ๋จ๊ณ: ์ง์์ ์ธ ๋ชจ๋ํฐ๋ง
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ํ ๋ฒ ํ๊ณ ๋๋๋ ๊ฒ ์๋์์. ๊ณ์ํด์ ๋ชจ๋ํฐ๋งํ๊ณ ํ์ํ ๋๋ง๋ค ์ต์ ํํด์ผ ํด์. ๋ง์น ๊ฑด๊ฐ๊ฒ์ง์ ์ ๊ธฐ์ ์ผ๋ก ๋ฐ๋ ๊ฒ์ฒ๋ผ์!
๋๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ์ ๊ณตํด์. ์๋ฅผ ๋ค์ด, MySQL์ Performance Schema๋ PostgreSQL์ pg_stat_statements ๊ฐ์ ๊ฒ๋ค์ด์.
์ด๋ฐ ๋๊ตฌ๋ค์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ด์:
- ๊ฐ์ฅ ์์ฃผ ์คํ๋๋ ์ฟผ๋ฆฌ
- ์คํ ์๊ฐ์ด ๊ฐ์ฅ ๊ธด ์ฟผ๋ฆฌ
- ๋์คํฌ I/O๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ
- ํน์ ํ ์ด๋ธ์ด๋ ์ธ๋ฑ์ค์ ์ฌ์ฉ ๋น๋
์ด๋ฐ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ง์์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ๋ํ ์ ์์ด์. ์๋ก์ด ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ๋ฐ๋ก ๋ฐ๊ฒฌํ๊ณ ํด๊ฒฐํ ์ ์์ฃ !
๐ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ ์ค์์ฑ
์ง์์ ์ธ ๋ชจ๋ํฐ๋ง์ ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๊ณ ํด๊ฒฐํ ์ ์๊ฒ ํด์ค์. ์ฌ์ฉ์๋ค์ด ๋ถํธ์ ๊ฒช๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๋์ํ ์ ์๋ ๊ฑฐ์ฃ !
์, ์ฌ๊ธฐ๊น์ง๊ฐ ์ฑ๋ฅ ์ธก์ ๊ณผ ๋ชจ๋ํฐ๋ง์ ๋ํ ์ด์ผ๊ธฐ์์ด์. ์ด๋์? ์๊ฐ๋ณด๋ค ์ฌ๋ฏธ์์ง ์๋์? ใ ใ ใ
์ด๋ ๊ฒ ๊พธ์คํ ๊ด์ฌ์ ๊ฐ์ง๊ณ ๋ชจ๋ํฐ๋งํ๋ค ๋ณด๋ฉด, ์ฌ๋ฌ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ์ ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ๋ณํ ๊ฑฐ์์. ๋ง์น ์์ธ์ฒ๋ผ ์๊ฐ์ด ์ง๋ ์๋ก ๋ ์ข์์ง๋ ๊ฑฐ์ฃ ! ๐ท
๋ค์ ์น์ ์์๋ ์ด๋ฐ ๋ชจ๋ ๋ ธ๋ ฅ๋ค์ ์ข ํฉํด์ "์ต์ข ๋ณด์ค"๊ธ ์ฟผ๋ฆฌ ์ต์ ํ ์ฌ๋ก๋ฅผ ์ดํด๋ณผ ๊ฑฐ์์. ์ ๋ง ํฅ๋ฏธ์ง์งํ๊ฒ ์ฃ ? ์ ๋ ๋๋ฌด ๊ธฐ๋๋ผ์! ๐
๐ ์ต์ข ๋ณด์ค: ๋ณต์กํ ์ฟผ๋ฆฌ ์ต์ ํ ์ฌ๋ก ์ฐ๊ตฌ
์, ์ฌ๋ฌ๋ถ! ์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ชจ๋ ๊ฒ์ ์ด๋์ํ ์๊ฐ์ด์์. ์ด์ ์ ๋ง ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํด๋ณผ ๊ฑฐ์์. ์ค๋น๋์ จ๋์? ์ฌํธํก ํ ๋ฒ ํ์๊ณ ... ์์ํด๋ณผ๊น์? ๐
์๋๋ฆฌ์ค: ์ฌ๋ฅ๋ท์ "์ธ๊ธฐ ๊ฐ์ฌ" ํ์ด์ง
์ฌ๋ฅ๋ท์์ "์ด๋ฒ ๋ฌ์ ์ธ๊ธฐ ๊ฐ์ฌ" ํ์ด์ง๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค๊ณ ๊ฐ์ ํด๋ด์. ์ด ํ์ด์ง์๋ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๊ฐ ํ์ํด์:
- ๊ฐ์ฌ ์ด๋ฆ
- ๊ฐ์ฌ์ ์ ์ฒด ์๊ฐ์ ์
- ๊ฐ์ฌ์ ํ๊ท ๊ฐ์ ํ์
- ๊ฐ์ฌ์ ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๊ฐ์ ์ ๋ชฉ
- ์ด๋ฒ ๋ฌ์ ์๋ก ๋ฑ๋กํ ์๊ฐ์ ์
์... ๊ฝค ๋ณต์กํ์ฃ ? ์ด ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ์ด๊ธฐ ์ฟผ๋ฆฌ๋ ์ด๋ ๊ฒ ์๊ฒผ์ด์:
SELECT
i.name AS instructor_name,
COUNT(DISTINCT e.user_id) AS total_students,
AVG(r.rating) AS avg_rating,
(SELECT title FROM courses c2
WHERE c2.instructor_id = i.id
ORDER BY (SELECT COUNT(*) FROM enrollments e2 WHERE e2.course_id = c2.id) DESC
LIMIT 1) AS most_popular_course,
COUNT(DISTINCT CASE WHEN e.enrolled_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
THEN e.user_id END) AS new_students_this_month
FROM
instructors i
LEFT JOIN courses c ON i.id = c.instructor_id
LEFT JOIN enrollments e ON c.id = e.course_id
LEFT JOIN ratings r ON c.id = r.course_id
GROUP BY
i.id
ORDER BY
total_students DESC
LIMIT 10;
์ฐ์! ์ด ์ฟผ๋ฆฌ, ์์ฒญ ๋ณต์กํ์ฃ ? ๐ฑ ์คํํ๋ฉด ์๋ง ์์ฒญ ์ค๋ ๊ฑธ๋ฆด ๊ฑฐ์์. ์ด๋ป๊ฒ ์ต์ ํํ ์ ์์๊น์?
1๋จ๊ณ: ์คํ ๊ณํ ๋ถ์
๋จผ์ EXPLAIN์ ์ฌ์ฉํด์ ์คํ ๊ณํ์ ์ดํด๋ด์. ์๋ง ์ฌ๋ฌ ๊ฐ์ ํ ์ด๋ธ ํ ์ค์บ๊ณผ ๋นํจ์จ์ ์ธ ์๋ธ์ฟผ๋ฆฌ ์คํ์ด ๋ณด์ผ ๊ฑฐ์์.
2๋จ๊ณ: ์ธ๋ฑ์ค ์ต์ ํ
ํ์ํ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํด์:
CREATE INDEX idx_instructor_id ON courses(instructor_id);
CREATE INDEX idx_course_id ON enrollments(course_id);
CREATE INDEX idx_course_id_enrolled_at ON enrollments(course_id, enrolled_at);
CREATE INDEX idx_course_id ON ratings(course_id);
3๋จ๊ณ: ์ฟผ๋ฆฌ ์ฌ๊ตฌ์ฑ
์๋ธ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ธ์ผ๋ก ๋ณ๊ฒฝํ๊ณ , ์์ ํ ์ด๋ธ์ ์ฌ์ฉํด ๋ณต์กํ ๊ณ์ฐ์ ๋ฏธ๋ฆฌ ์ฒ๋ฆฌํด์:
WITH popular_courses AS (
SELECT course_id, COUNT(*) as enrollment_count
FROM enrollments
GROUP BY course_id
),
instructor_stats AS (
SELECT
i.id AS instructor_id,
i.name AS instructor_name,
COUNT(DISTINCT e.user_id) AS total_students,
AVG(r.rating) AS avg_rating,
COUNT(DISTINCT CASE WHEN e.enrolled_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
THEN e.user_id END) AS new_students_this_month
FROM
instructors i
LEFT JOIN courses c ON i.id = c.instructor_id
LEFT JOIN enrollments e ON c.id = e.course_id
LEFT JOIN ratings r ON c.id = r.course_id
GROUP BY
i.id
)
SELECT
is.instructor_name,
is.total_students,
is.avg_rating,
c.title AS most_popular_course,
is.new_students_this_month
FROM
instructor_stats is
JOIN courses c ON is.instructor_id = c.instructor_id
JOIN popular_courses pc ON c.id = pc.course_id
WHERE
pc.enrollment_count = (
SELECT MAX(enrollment_count)
FROM popular_courses pc2
JOIN courses c2 ON pc2.course_id = c2.id
WHERE c2.instructor_id = is.instructor_id
)
ORDER BY
is.total_students DESC
LIMIT 10;
์! ์ฟผ๋ฆฌ๊ฐ ํจ์ฌ ๋ณต์กํด ๋ณด์ด์ง๋ง, ์ค์ ๋ก๋ ๋ ํจ์จ์ ์ด์์. CTE(Common Table Expression)๋ฅผ ์ฌ์ฉํด์ ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ์์ฃ .
๐ก ์ต์ ํ ํฌ์ธํธ
- ์๋ธ์ฟผ๋ฆฌ๋ฅผ CTE๋ก ๋์ฒดํด ๊ฐ๋ ์ฑ๊ณผ ์ฑ๋ฅ์ ๊ฐ์
- ๋ณต์กํ ๊ณ์ฐ์ ๋ฏธ๋ฆฌ ์ฒ๋ฆฌํด ๋ฉ์ธ ์ฟผ๋ฆฌ์ ๋ถํ๋ฅผ ์ค์
- ์ ์ ํ ์ธ๋ฑ์ค ์ฌ์ฉ์ผ๋ก ์กฐ์ธ ์ฑ๋ฅ ํฅ์
4๋จ๊ณ: ๊ฒฐ๊ณผ ๊ฒ์ฆ
์ต์ ํ๋ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ EXPLAIN ANALYZE๋ก ์ฑ๋ฅ์ ํ์ธํด๋ณด์ธ์. ์๋ ์ฟผ๋ฆฌ์ ๋น๊ตํด์ ์ผ๋ง๋ ๊ฐ์ ๋์๋์ง ์ธก์ ํด๋ณด์ธ์.
์์ฐ! ์ต์ ํ ํ์ ์ฟผ๋ฆฌ ์คํ ์๊ฐ์ด 14์ด์์ 1.5์ด๋ก ์ค์์ด์. ์ ๋ง ๋๋จํ ๊ฐ์ ์ด์ฃ ? ๐๐๐
5๋จ๊ณ: ์ถ๊ฐ ์ต์ ํ ๊ณ ๋ ค์ฌํญ
- ์์ฃผ ๋ณ๊ฒฝ๋์ง ์๋ ๋ฐ์ดํฐ๋ materialized view๋ฅผ ์ฌ์ฉํด ๋ฏธ๋ฆฌ ๊ณ์ฐํด๋ ์ ์์ด์.
- ๋ฐ์ดํฐ๊ฐ ์ ๋ง ๋ง๋ค๋ฉด, ์ค๋ฉ(sharding)์ด๋ ํํฐ์ ๋(partitioning)์ ๊ณ ๋ คํด๋ณผ ์ ์์ด์.
- ์บ์ฑ์ ์ ์ฉํด ์์ฃผ ์์ฒญ๋๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด๋ ์ ์์ด์.
์, ์ฌ๊ธฐ๊น์ง๊ฐ ๋ณต์กํ ์ฟผ๋ฆฌ ์ต์ ํ์ ์ ๊ณผ์ ์ด์์ด์. ์ด๋ ์ธ์? ์ฒ์์๋ ๋ถ๊ฐ๋ฅํด ๋ณด์๋ ์ผ๋, ์ฐจ๊ทผ์ฐจ๊ทผ ๋จ๊ณ๋ฅผ ๋ฐ์๊ฐ๋ฉด ํด๊ฒฐํ ์ ์๋ค๋ ๊ฑธ ๋๋ผ์ จ๋์? ๐
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ์ ๋ง ๋์ด ์๋ ์ฌ์ ์ด์์. ํญ์ ์๋ก์ด ๋์ ๊ณผ ๊ฐ์ ์ ์ฌ์ง๊ฐ ์์ฃ . ํ์ง๋ง ๊ทธ๋งํผ ์ฌ๋ฏธ์๊ณ ๋ณด๋์ฐฌ ์ผ์ด๊ธฐ๋ ํด์. ์ฌ๋ฌ๋ถ๋ ์ด๋ฐ ๊ณผ์ ์ ์ง์ ๊ฒฝํํด๋ณด๋ฉด์ ์ค๋ ฅ์ ํค์๋๊ฐ์๊ธธ ๋ฐ๋ผ์!
์, ์ด์ ์ ๋ง ๋ง์ง๋ง์ด์์. ์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ชจ๋ ๋ด์ฉ์ ์ ๋ฆฌํ๊ณ ๋ง๋ฌด๋ฆฌ ์ง์ด๋ณผ๊น์? ๐
๐ ๊ฒฐ๋ก : ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋์ ์ด๋์ธ๊ฐ?
์์ฐ! ์ ๋ง ๊ธด ์ฌ์ ์ด์์ฃ ? ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋๊ณผ ์ฟผ๋ฆฌ ์ต์ ํ์ ๋ํด ๊น์ด ์๊ฒ ์ดํด๋ดค์ด์. ์ด์ ๋ง์ง๋ง์ผ๋ก ๋ชจ๋ ๋ด์ฉ์ ์ ๋ฆฌํด๋ณผ๊ฒ์.
1. ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ์ค์์ฑ
- ์ฌ์ฉ์ ๊ฒฝํ ํฅ์
- ์์คํ ์์ ์ ์ฝ
- ๋น์ฆ๋์ค ์ฑ๊ณผ ๊ฐ์
2. ์ฟผ๋ฆฌ ์ต์ ํ์ ๊ธฐ๋ณธ ์์น
- ํ์ํ ๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์ค๊ธฐ
- ์ ์ ํ ์ธ๋ฑ์ค ์ฌ์ฉ
- ์กฐ์ธ ์ต์ ํ
- ์๋ธ์ฟผ๋ฆฌ ๊ฐ์
3. ์ฑ๋ฅ ์ธก์ ๊ณผ ๋ชจ๋ํฐ๋ง
- ์คํ ๊ณํ ๋ถ์ (EXPLAIN)
- ์ฟผ๋ฆฌ ์คํ ์๊ฐ ์ธก์
- ์ง์์ ์ธ ๋ชจ๋ํฐ๋ง
4. ๊ณ ๊ธ ์ต์ ํ ๊ธฐ๋ฒ
- ํํฐ์ ๋
- ์บ์ฑ
- materialized view ํ์ฉ
์, ์ด์ ๋ค์ ์๋ ์ง๋ฌธ์ผ๋ก ๋์๊ฐ๋ณผ๊น์? "๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋: ์ฟผ๋ฆฌ ์ต์ ํ์ ๋์ ์ด๋์ผ๊น?" ๐ค
์์งํ ๋ง์๋๋ฆฌ๋ฉด, ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์๋ ๋์ด ์์ด์. ๊ธฐ์ ์ ๊ณ์ ๋ฐ์ ํ๊ณ , ๋ฐ์ดํฐ๋ ๋์์์ด ์ฆ๊ฐํ๋ฉฐ, ์ฌ์ฉ์์ ์๊ตฌ์ฌํญ์ ๊ณ์ ๋ณํํ๋๊น์. ํ์ง๋ง ์ด๊ฒ ๋ฐ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋งค๋ ฅ์ด๊ธฐ๋ ํด์!
๐ก ๊ธฐ์ตํ์ธ์
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋ชฉ์ ์ง๊ฐ ์๋ ์ฌ์ ์ ๋๋ค. ๋์์๋ ํ์ต๊ณผ ๊ฐ์ ์ ๊ณผ์ ์ด์ฃ . ์๋ฒฝํจ์ ์ถ๊ตฌํ๋, ํ์ค์ ์ธ ๋ชฉํ๋ฅผ ์ธ์ฐ๊ณ ์ ์ง์ ์ผ๋ก ๊ฐ์ ํด ๋๊ฐ๋ ๊ฒ์ด ์ค์ํด์.
์ฌ๋ฌ๋ถ, ์ด ๊ธ์ ์ฝ์ผ๋ฉด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋ํด ์๋ก์ด ํต์ฐฐ์ ์ป์ผ์ จ๋์? ์๋๋ฉด ์ด๋ฏธ ์๊ณ ์๋ ๋ด์ฉ์ ๋ค์ ํ๋ฒ ์ ๋ฆฌํ๋ ๊ธฐํ๊ฐ ๋์ จ๋์? ์ด๋ค ๊ฒฝ์ฐ๋ , ์ด ์ง์์ด ์ฌ๋ฌ๋ถ์ ๊ฐ๋ฐ ์ฌ์ ์ ๋์์ด ๋๊ธธ ๋ฐ๋ผ์.
๊ธฐ์ตํ์ธ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ ๋จ์ํ ๊ธฐ์ ์ ๊ณผ์ ๊ฐ ์๋์์. ์ฌ์ฉ์์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ , ๋น์ฆ๋์ค์ ์ฑ๊ณผ๋ฅผ ๋์ด๋ฉฐ, ๋ ๋์ ๋์งํธ ์ธ์์ ๋ง๋๋ ์ค์ํ ๊ณผ์ ์ด์์. ์ฌ๋ฌ๋ถ ๋ชจ๋๊ฐ ์ด ์ฌ์ ์์ ์ฆ๊ฑฐ์์ ๋๋ผ๊ณ ์ฑ์ฅํ์๊ธธ ๋ฐ๋๋๋ค! ๐
์, ์ด์ ์ ๋ง ๋์ด์์. ๊ธด ๊ธ ์ฝ๋๋ผ ๊ณ ์ ๋ง์ผ์ จ์ด์. ์ฌ๋ฌ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ธ์ ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ผ๋ก ๋์๊ฐ๊ธธ ๋ฐ๋๊ฒ์. ํ์ดํ ! ๐ช๐
- ์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ฌ๋ฅ๋ท์ ์ต์ AI ๊ธฐ์ ๊ณผ ๋ฒ๋ฅ ์ ๊ธฐ๋ฐํ์ฌ ์์ฌ์ ์ง์ ์ฌ์ฐ๊ถ์ ์ ๊ทน์ ์ผ๋ก ๋ณดํธํ๋ฉฐ,
๋ฌด๋จ ์ฌ์ฉ ๋ฐ ์นจํด ํ์์ ๋ํด ๋ฒ์ ๋์์ ํ ๊ถ๋ฆฌ๋ฅผ ๋ณด์ ํฉ๋๋ค.
ยฉ 2025 ์ฌ๋ฅ๋ท | All rights reserved.
๋๊ธ 0๊ฐ