๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „์— ๋ณด๋Š” ๊ฒƒ๋“ค

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „์— ๋ณด๋Š” ๊ฒƒ๋“ค ์ธ๋ฑ์Šค๊ฐ€ ์™œ ๋น ๋ฅธ์ง€(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์— ๊ฐ€๊นŒ์šฐ๋ฉด(์ค‘๋ณต์ด ๋งŽ์œผ๋ฉด) ์ธ๋ฑ์Šค๋ฅผ ํƒ€๋„ ๊ฒฐ๊ตญ ๋งŽ์€ ํ–‰์„ ์ฝ์–ด์•ผ ํ•ด์„œ ์ด๋“์ด ์ ๋‹ค.

์ปฌ๋Ÿผ ๊ณ ์œ ๊ฐ’ ์„ ํƒ๋„ ์ธ๋ฑ์Šค ํšจ๊ณผ
email ํ–‰๋งˆ๋‹ค ๊ฑฐ์˜ ๊ณ ์œ  ≈ 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๋กœ ์‹ค์ œ ์‹คํ–‰ ๊ณ„ํš์„ ๋ณด๊ณ , ์šด์˜๊ณผ ๋น„์Šทํ•œ ๋ฐ์ดํ„ฐ์—์„œ ์ „ํ›„๋ฅผ ๋น„๊ตํ•˜๋Š” ์Šต๊ด€์ด ๊ฐ€์žฅ ํ™•์‹คํ•˜๋‹ค. ์ต์ˆ™ํ•œ ๊ฐœ๋…์ผ์ˆ˜๋ก ์ด ์ž‘์€ ํŒ๋‹จ ์ฐจ์ด๊ฐ€ ์šด์˜ ํ’ˆ์งˆ์„ ํฌ๊ฒŒ ๋ฐ”๊พผ๋‹ค.


์ฐธ๊ณ  ์ถœ์ฒ˜