๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๊ธฐ ์ ์ ๋ณด๋ ๊ฒ๋ค ์ธ๋ฑ์ค๊ฐ ์ ๋น ๋ฅธ์ง(B-Tree, O(log n)), ์ ํ๋๊ฐ ๋ฎ์ผ๋ฉด ์ ์ ๋ฃ๋์ง, ์ถ๊ฐ ์ ๋ฌด์์ ํ์ธํ ์ง๋ฅผ SQL ์์ ์ ํจ๊ป ์ ๋ฆฌํ๋ค.
๋ค์ด๊ฐ๋ฉฐ
์กฐํ๊ฐ ๋๋ฆฌ๋ฉด ๊ฐ์ฅ ๋จผ์ ๋ ์ค๋ฅด๋ ์ฒ๋ฐฉ์ด ์ธ๋ฑ์ค๋ค. ๊ทธ๋ฆฌ๊ณ ๋๊ฐ๋ ํจ๊ณผ๋ฅผ ๋ณธ๋ค. ๋ฌธ์ ๋ ์ธ๋ฑ์ค๊ฐ ๊ณต์ง๊ฐ ์๋๋ผ๋ ์ ์ด๋ค.
์ฝ๊ธฐ๋ฅผ ๋น ๋ฅด๊ฒ ๋ง๋๋ ๋์ ์ฐ๊ธฐ๋ฅผ ๋๋ฆฌ๊ฒ ํ๊ณ , ์ ์ฅ ๊ณต๊ฐ์ ๋ ์ด๋ค.
๊ทธ๋์ "๋๋ฆฌ๋๊น ์ธ๋ฑ์ค ์ถ๊ฐ"๊ฐ ์๋๋ผ, ๋ฌด์์ ์ป๊ณ ๋ฌด์์ ๋ด์ฃผ๋์ง ์๊ณ ์ถ๊ฐํด์ผ ํ๋ค.
์ธ๋ฑ์ค๋ ๊ฒ์์ ๋น ๋ฅด๊ฒ ๋ง๋๋ ๋๊ตฌ์ง๋ง, ์ฐ๊ธฐ ์ฑ๋ฅ๊ณผ ์ ์ฅ ๊ณต๊ฐ์ ๋๊ฐ๋ก ๊ฐ์ ธ๊ฐ๋ค.
์ด ๊ธ์์๋ ์ธ๋ฑ์ค๊ฐ ์ ๋น ๋ฅธ์ง(B-Tree์ ๋ณต์ก๋), ์ธ์ ํจ๊ณผ๊ฐ ์๋์ง(์ ํ๋), ๊ทธ๋ฆฌ๊ณ ์ถ๊ฐ ์ ์ ๋ฌด์์ ํ์ธํด์ผ ํ๋์ง๋ฅผ SQL ์์ ์ ํจ๊ป ์ ๋ฆฌํ๋ค.
์ธ๋ฑ์ค๋ ์ ๋น ๋ฅธ๊ฐ — B-Tree์ ๋ณต์ก๋
์ธ๋ฑ์ค๊ฐ ์์ผ๋ฉด DB๋ ์ํ๋ ํ์ ์ฐพ๊ธฐ ์ํด ํ ์ด๋ธ ์ ์ฒด๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ํ๋๋ค. ์ด๊ฑธ ํ ํ ์ด๋ธ ์ค์บ(Full Table Scan) ์ด๋ผ ํ๊ณ , ํ์ด $n$๊ฐ๋ฉด ๋น์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
$$T_{\text{full scan}} = O(n)$$
๋๋ถ๋ถ์ RDBMS ์ธ๋ฑ์ค๋ B-Tree(์ ํํ๋ B+Tree) ๊ตฌ์กฐ๋ค. ์ ๋ ฌ๋ ํธ๋ฆฌ๋ผ์, ์ฐพ์ผ๋ ค๋ ๊ฐ์ ๋ฃจํธ์์ ์์ํด ๋จ๊ณ์ ์ผ๋ก ์ขํ๊ฐ๋ค. ํ ๋ ธ๋๊ฐ $b$๊ฐ์ ์์์ ๊ฐ์ง ์ ์๋ค๋ฉด ํ์ ๋น์ฉ์ ํธ๋ฆฌ์ ๋์ด์ ๋น๋กํ๋ค.
$$T_{\text{index scan}} = O(\log_b n)$$
์ด ์ฐจ์ด๋ ๋ฐ์ดํฐ๊ฐ ์ปค์ง์๋ก ๊ทน์ ์ด๋ค. ์๋ฅผ ๋ค์ด ํ์ด 100๋ง ๊ฐ($n = 10^6$)์ด๊ณ ํ ๋ ธ๋๊ฐ ์์์ 100๊ฐ์ฉ ๊ฐ์ง๋ค๋ฉด($b = 100$):
$$\log_{100}(10^6) = 3$$
ํ ์ค์บ์ ์ต๋ 100๋ง ๋ฒ ์ฝ์ด์ผ ํ์ง๋ง, B-Tree๋ ๋จ 3๋จ๊ณ๋ง์ ๋๋ฌํ๋ค. ์ธ๋ฑ์ค๊ฐ ๋น ๋ฅธ ์ด์ ๊ฐ ๋ฐ๋ก ์ด๊ฒ์ด๋ค.
B-Tree ํ์ (user_id = 42 ์ฐพ๊ธฐ)
[50] ← ๋ฃจํธ: 42 < 50, ์ผ์ชฝ์ผ๋ก
/ \
[20] [80] ← 42 > 20, ์ค๋ฅธ์ชฝ์ผ๋ก
/ \ / \
... [30,42,48] ... ← ๋ฆฌํ ๋
ธ๋์์ 42 ๋ฐ๊ฒฌ
์นด๋๋๋ฆฌํฐ์ ์ ํ๋ — ์ธ๋ฑ์ค๊ฐ ํญ์ ๋น ๋ฅธ ๊ฑด ์๋๋ค
์ฌ๊ธฐ์ ์ค์ํ ํจ์ ์ด ์๋ค. ์ธ๋ฑ์ค๋ฅผ ํ๋ค๊ณ ํญ์ ๋น ๋ฅธ ๊ฒ ์๋๋ค. ํต์ฌ ๊ฐ๋ ์ด ์ ํ๋(selectivity) ๋ค.
$$\text{์ ํ๋} = \frac{\text{๊ณ ์ ๊ฐ(distinct)์ ๊ฐ์}}{\text{์ ์ฒด ํ์ ๊ฐ์}}$$
์ ํ๋๊ฐ 1์ ๊ฐ๊น์ธ์๋ก(๊ณ ์ ๊ฐ์ด ๋ง์์๋ก) ์ธ๋ฑ์ค๊ฐ ํจ๊ณผ์ ์ด๋ค. ๋ฐ๋๋ก 0์ ๊ฐ๊น์ฐ๋ฉด(์ค๋ณต์ด ๋ง์ผ๋ฉด) ์ธ๋ฑ์ค๋ฅผ ํ๋ ๊ฒฐ๊ตญ ๋ง์ ํ์ ์ฝ์ด์ผ ํด์ ์ด๋์ด ์ ๋ค.
| ์ปฌ๋ผ | ๊ณ ์ ๊ฐ | ์ ํ๋ | ์ธ๋ฑ์ค ํจ๊ณผ |
| ํ๋ง๋ค ๊ฑฐ์ ๊ณ ์ | ≈ 1.0 | ๋งค์ฐ ์ข์ | |
| user_id | ์ฌ์ฉ์ ์๋งํผ | ๋์ | ์ข์ |
| status (5์ข ) | 5๊ฐ | ๋ฎ์ | ์ฝํจ |
| gender | 2๊ฐ | ≈ 0.0 | ๊ฑฐ์ ๋ฌด์๋ฏธ |
gender์ฒ๋ผ ๊ฐ์ด ๋ ์ข ๋ฅ๋ฟ์ธ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ๊ฑธ๋ฉด, WHERE gender = 'M' ์กฐ๊ฑด์ด ์ ์ฒด์ ์ ๋ฐ์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ตํฐ๋ง์ด์ ๋ ์ฐจ๋ผ๋ฆฌ ํ ์ค์บ์ ํํ๋ค. ์ ํ๋๊ฐ ๋ฎ์ ์ปฌ๋ผ์ ๋จ์ผ ์ธ๋ฑ์ค๋ ์ถ๊ฐํด๋ ์ ์ฐ์ธ๋ค.
์ค๋ฌด ๊ฒฝํ์น์ผ๋ก, ์ฟผ๋ฆฌ๊ฐ ์ ์ฒด ํ์ ๋๋ต 5~10% ์ดํ๋ฅผ ๋ฐํํ ๋ ์ธ๋ฑ์ค๊ฐ ์๋ฏธ ์๋ค.
EXPLAIN์ผ๋ก ์ค์ ํ์ธํ๊ธฐ
์ถ์ธก ๋์ ์คํ ๊ณํ์ ๋ด์ผ ํ๋ค. EXPLAIN ANALYZE๋ ์ตํฐ๋ง์ด์ ๊ฐ ์ด๋ค ๊ฒฝ๋ก๋ฅผ ํํ๊ณ ์ค์ ์๊ฐ์ด ์ผ๋ง๋ ๊ฑธ๋ ธ๋์ง ๋ณด์ฌ์ค๋ค.
์ธ๋ฑ์ค๊ฐ ์์ ๋:
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 42;
Seq Scan on orders (cost=0.00..18584.00 rows=12 width=64)
(actual time=0.512..142.339 rows=11 loops=1)
Filter: (user_id = 42)
Rows Removed by Filter: 999989
Planning Time: 0.084 ms
Execution Time: 142.401 ms
Seq Scan(์์ฐจ ์ค์บ)์ผ๋ก 100๋ง ํ์ ํ์ด 999,989ํ์ ๋ฒ๋ฆฌ๊ณ 11ํ๋ง ๊ฑด์ก๋ค. 142ms๊ฐ ๊ฑธ๋ ธ๋ค.
์ด์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ค.
CREATE INDEX idx_orders_user_id ON orders(user_id);
Index Scan using idx_orders_user_id on orders
(cost=0.42..8.59 rows=11 width=64)
(actual time=0.031..0.045 rows=11 loops=1)
Index Cond: (user_id = 42)
Planning Time: 0.121 ms
Execution Time: 0.067 ms
Index Scan์ผ๋ก ๋ฐ๋์๊ณ ์คํ ์๊ฐ์ด 142ms → 0.067ms๋ก ์ฝ 2000๋ฐฐ ๋นจ๋ผ์ก๋ค. Rows Removed by Filter๊ฐ ์ฌ๋ผ์ง ๊ฒ์ ์ฃผ๋ชฉํ์. ๋ฒ๋ฆฌ๋ ํ ์์ด ํ์ํ ํ๋ง ์ ํํ ์ฝ์๋ค.
๋ณตํฉ ์ธ๋ฑ์ค — ์ปฌ๋ผ ์์๊ฐ ์ ๋ถ๋ค
์ฌ๋ฌ ์ปฌ๋ผ์ ๋ฌถ๋ ๋ณตํฉ ์ธ๋ฑ์ค(composite index)๋ ์ปฌ๋ผ ์์๊ฐ ์ฑ๋ฅ์ ์ข์ฐํ๋ค. B-Tree๋ ์ผ์ชฝ ์ปฌ๋ผ๋ถํฐ ์ ๋ ฌํ๊ธฐ ๋๋ฌธ์, ๋งจ ์ผ์ชฝ ์ปฌ๋ผ(leftmost prefix) ๋ถํฐ ์กฐ๊ฑด์ ์จ์ผ ์ธ๋ฑ์ค๋ฅผ ํ๋ค.
CREATE INDEX idx_orders_user_created
ON orders(user_id, created_at DESC);
์ด ์ธ๋ฑ์ค๋ ๋ค์ ์ฟผ๋ฆฌ์ ๋ชจ๋ ํจ๊ณผ์ ์ด๋ค.
-- O: user_id ๋จ๋
(๋งจ ์ผ์ชฝ ์ปฌ๋ผ)
SELECT * FROM orders WHERE user_id = 42;
-- O: user_id + created_at (์ผ์ชฝ๋ถํฐ ์์๋๋ก)
SELECT * FROM orders
WHERE user_id = 42
ORDER BY created_at DESC;
ํ์ง๋ง ๋ค์ ์ฟผ๋ฆฌ๋ ์ด ์ธ๋ฑ์ค๋ฅผ ์ ๋๋ก ๋ชป ์ด๋ค.
-- X: created_at๋ง ์กฐ๊ฑด (๋งจ ์ผ์ชฝ user_id๋ฅผ ๊ฑด๋๋)
SELECT * FROM orders WHERE created_at > '2026-01-01';
created_at๋ง์ผ๋ก ์กฐํํ๋ ค๋ฉด ์ธ๋ฑ์ค์ ์ฒซ ์ปฌ๋ผ user_id๋ฅผ ๊ฑด๋๋ฐ๊ฒ ๋๋๋ฐ, B-Tree๋ ์ด๋ฐ ์ ๊ทผ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ์ง ๋ชปํ๋ค. ๊ทธ๋์ ๋ณตํฉ ์ธ๋ฑ์ค์ ์ปฌ๋ผ ์์๋ ์์ฃผ ์ฐ๋ ์กฐ๊ฑด → ์ ๋ ฌ ์กฐ๊ฑด ์์ผ๋ก, ๊ทธ๋ฆฌ๊ณ ์ ํ๋๊ฐ ๋์ ์ปฌ๋ผ์ ์์ ๋๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
์ ํ๋ฒํธ๋ถ๊ฐ "์ฑ → ์ด๋ฆ" ์์ผ๋ก ์ ๋ ฌ๋ผ ์์ผ๋ฉด ์ฑ์ผ๋ก๋ ๋นจ๋ฆฌ ์ฐพ์ง๋ง, ์ด๋ฆ๋ง ์ ๋๋ ์ฒ์๋ถํฐ ๋ค ๋ค์ ธ์ผ ํ๋ ๊ฒ๊ณผ ๊ฐ๋ค.
์ปค๋ฒ๋ง ์ธ๋ฑ์ค — ํ ์ด๋ธ์ ์์ ์ ์ฝ๋๋ค
์ธ๋ฑ์ค๋ก ํ์ ์์น๋ฅผ ์ฐพ์ ๋ค, ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ผ๋ฌ ํ ์ด๋ธ์ ๋ค์ ์ ๊ทผํ๋ ๊ณผ์ ์ ๋ณดํต ๋๋ฐํ๋ค. ๊ทธ๋ฐ๋ฐ ์ฟผ๋ฆฌ๊ฐ ํ์๋ก ํ๋ ์ปฌ๋ผ์ด ๋ชจ๋ ์ธ๋ฑ์ค ์์ ์๋ค๋ฉด, ํ ์ด๋ธ์ ์ฝ์ง ์๊ณ ์ธ๋ฑ์ค๋ง์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์๋ค. ์ด๊ฑธ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค(covering index) ๋๋ ์ธ๋ฑ์ค ์จ๋ฆฌ ์ค์บ์ด๋ผ ํ๋ค.
-- user_id๋ก ์กฐํํด์ created_at๋ง ํ์ํ ๊ฒฝ์ฐ
SELECT created_at FROM orders WHERE user_id = 42;
-- ์ด ์ธ๋ฑ์ค๋ user_id์ created_at์ ๋ชจ๋ ๋ด๊ณ ์๋ค
CREATE INDEX idx_orders_user_created
ON orders(user_id, created_at);
Index Only Scan using idx_orders_user_created on orders
Index Cond: (user_id = 42)
Index Only Scan์ด ๋จ๋ฉด ํ ์ด๋ธ ์ ๊ทผ์ ์๋ตํ ๊ฒ์ด๋ค. ์์ฃผ ํจ๊ป ์กฐํ๋๋ ์ปฌ๋ผ์ ์ธ๋ฑ์ค์ ํฌํจ์ํค๋ฉด ์ถ๊ฐ I/O๋ฅผ ์ค์ผ ์ ์๋ค. (PostgreSQL์ INCLUDE ์ ๋ก, ๊ฒ์์๋ ์ ์ฐ์ง๋ง ๊ฒฐ๊ณผ์ ํ์ํ ์ปฌ๋ผ์ ๋ฐ๋ก ๋ด์ ์๋ ์๋ค.)
์ธ๋ฑ์ค์ ๋น์ฉ — ๊ณต์ง๊ฐ ์๋๋ค
์ฌ๊ธฐ๊น์ง๋ง ๋ณด๋ฉด ์ธ๋ฑ์ค๋ฅผ ๋ง์ด ๋ง๋ค์๋ก ์ข์ ๋ณด์ธ๋ค. ํ์ง๋ง ์ธ๋ฑ์ค๋ ๋ถ๋ช ํ ๋๊ฐ๊ฐ ์๋ค.
1. ์ฐ๊ธฐ ์ฑ๋ฅ ์ ํ. ํ์ INSERT/UPDATE/DELETEํ ๋๋ง๋ค, ๊ทธ ํ ์ด๋ธ์ ๊ฑธ๋ฆฐ ๋ชจ๋ ์ธ๋ฑ์ค๋ ํจ๊ป ๊ฐฑ์ ํด์ผ ํ๋ค. ์ธ๋ฑ์ค๊ฐ 5๊ฐ๋ฉด INSERT ํ ๋ฒ์ ์ธ๋ฑ์ค 5๊ฐ๋ฅผ ์์ ํ๋ค. ๋๋ ๋ฐฐ์น ์ ๋ ฅ์์ ์ด ๋น์ฉ์ด ํนํ ํฌ๋ค.
2. ์ ์ฅ ๊ณต๊ฐ. ์ธ๋ฑ์ค๋ ๋ณ๋์ ๋์คํฌ ๊ณต๊ฐ์ ์ฐจ์งํ๋ค. ์ปฌ๋ผ์ด ๋ง์ ๋ณตํฉ ์ธ๋ฑ์ค๋ ํ ์คํธ ์ปฌ๋ผ ์ธ๋ฑ์ค๋ ํ ์ด๋ธ ๋ชป์ง์๊ฒ ์ปค์ง๊ธฐ๋ ํ๋ค.
3. ์ตํฐ๋ง์ด์ ๋ถ๋ด. ์ธ๋ฑ์ค๊ฐ ๋๋ฌด ๋ง์ผ๋ฉด ์ตํฐ๋ง์ด์ ๊ฐ ์ด๋ค ์ธ๋ฑ์ค๋ฅผ ์ธ์ง ๊ณ ๋ฅด๋ ๋น์ฉ ์์ฒด๊ฐ ๋๊ณ , ์๋ชป๋ ์ธ๋ฑ์ค๋ฅผ ์ ํํ ์ฌ์ง๋ ์๊ธด๋ค.
๊ทธ๋์ ์ ์ฐ๋ ์ธ๋ฑ์ค๋ ์คํ๋ ค ํด๋กญ๋ค. ์ค์ ๋ก ์ฌ์ฉ๋๋์ง ํต๊ณ๋ก ํ์ธํ ์ ์๋ค.
-- PostgreSQL: ์ธ๋ฑ์ค ์ฌ์ฉ ํ์ ํ์ธ (idx_scan = 0์ด๋ฉด ๋ฏธ์ฌ์ฉ)
SELECT indexrelname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
WHERE relname = 'orders'
ORDER BY idx_scan ASC;
idx_scan์ด 0์ธ ์ธ๋ฑ์ค๋ ํ ๋ฒ๋ ์ ์ฐ์ธ ๊ฒ์ด๋ ์ ๊ฑฐ ํ๋ณด๋ค.
์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ฉด ์ ๋๋ ๊ฒฝ์ฐ
๋ค์ ์ํฉ์์๋ ์ธ๋ฑ์ค๊ฐ ๋๋ณด๋ค ์ค์ด ํฌ๋ค.
- ์ ํ๋๊ฐ ๋ฎ์ ์ปฌ๋ผ: gender, status ๊ฐ์ด ๊ฐ ์ข ๋ฅ๊ฐ ์ ์ ๋จ์ผ ์ปฌ๋ผ
- ์ฐ๊ธฐ๊ฐ ์๋์ ์ผ๋ก ๋ง์ ํ ์ด๋ธ: ๋ก๊ทธ ํ ์ด๋ธ์ฒ๋ผ INSERT ์์ฃผ๋ฉด ์ธ๋ฑ์ค ๊ฐฑ์ ๋น์ฉ์ด ๋ ํผ
- ์์ ํ ์ด๋ธ: ์๋ฐฑ ํ์ง๋ฆฌ๋ ํ ์ค์บ์ด ๋ ๋น ๋ฅผ ์ ์์
- ์์ฃผ ๋ฐ๋๋ ์ปฌ๋ผ: UPDATE๊ฐ ์ฆ์ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ ๊ทธ๋งํผ ์์ฃผ ์ฌ๊ตฌ์ฑ๋จ
์ ์ฉ ์ ์ฒดํฌ๋ฆฌ์คํธ
์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๊ธฐ ์ ์ ์๋๋ฅผ ํ์ธํ๋ฉด ๋๋ถ๋ถ์ ์ค์๋ฅผ ํผํ ์ ์๋ค.
- ๋๋ฆฐ ์ฟผ๋ฆฌ์ EXPLAIN ANALYZE๋ฅผ ์บก์ฒํ๋๊ฐ (์ถ์ธก ๊ธ์ง)
- ๋์ ์ปฌ๋ผ์ ์ ํ๋๊ฐ ์ถฉ๋ถํ ๋์๊ฐ
- ๋ณตํฉ ์ธ๋ฑ์ค๋ผ๋ฉด ์ปฌ๋ผ ์์๋ฅผ ์ฟผ๋ฆฌ ์กฐ๊ฑด·์ ๋ ฌ์ ๋ง์ท๋๊ฐ
- ์ธ๋ฑ์ค ์ถ๊ฐ ํ ์ฐ๊ธฐ ์ฑ๋ฅ๋ ์ธก์ ํ๋๊ฐ
- ์ด์ ๋ฐ์ดํฐ ๋ถํฌ์ ๋น์ทํ ํ๊ฒฝ์์ ํ ์คํธํ๋๊ฐ (๊ฐ๋ฐ DB์ ์์ ๋ฐ์ดํฐ๋ก ํ๋จ ๊ธ์ง)
- ๊ธฐ์กด์ ์ ์ฐ์ด๋ ์ธ๋ฑ์ค(idx_scan = 0)๋ ์๋๊ฐ
๋ง์น๋ฉฐ
์ธ๋ฑ์ค๋ "๋๋ฆฌ๋ฉด ์ถ๊ฐํ๋ ๊ฒ"์ด ์๋๋ผ, ์ฝ๊ธฐ ์๋์ ์ฐ๊ธฐ ๋น์ฉ·์ ์ฅ ๊ณต๊ฐ ์ฌ์ด์ ํธ๋ ์ด๋์คํ๋ฅผ ์ดํดํ๊ณ ์ ํํ๋ ๊ฒ์ด๋ค. ํต์ฌ์ ์ธ ๊ฐ์ง๋ค. B-Tree ๋๋ถ์ $O(\log n)$์ผ๋ก ๋นจ๋ผ์ง๋ค๋ ์๋ฆฌ, ์ ํ๋๊ฐ ๋ฎ์ผ๋ฉด ํจ๊ณผ๊ฐ ์๋ค๋ ์ , ๊ทธ๋ฆฌ๊ณ ์ธ๋ฑ์ค๋ ์ฐ๊ธฐ ๋น์ฉ์ ๋๋ฐํ๋ค๋ ์ฌ์ค.
์ถ์ธก์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ๋๋ฆฌ๊ธฐ๋ณด๋ค EXPLAIN ANALYZE๋ก ์ค์ ์คํ ๊ณํ์ ๋ณด๊ณ , ์ด์๊ณผ ๋น์ทํ ๋ฐ์ดํฐ์์ ์ ํ๋ฅผ ๋น๊ตํ๋ ์ต๊ด์ด ๊ฐ์ฅ ํ์คํ๋ค. ์ต์ํ ๊ฐ๋ ์ผ์๋ก ์ด ์์ ํ๋จ ์ฐจ์ด๊ฐ ์ด์ ํ์ง์ ํฌ๊ฒ ๋ฐ๊พผ๋ค.
์ฐธ๊ณ ์ถ์ฒ
- PostgreSQL ๊ณต์ ๋ฌธ์: Indexes — https://www.postgresql.org/docs/current/indexes.html
- Use The Index, Luke! (B-Tree ์ธ๋ฑ์ค ์ค๋ช ) — https://use-the-index-luke.com/
- MySQL: Optimization and Indexes — https://dev.mysql.com/doc/refman/8.0/en/optimization-indexes.html