ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

๐Ÿ“Œ PostgreSQL๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ: ์ด๋ก ๊ณผ ์‹ค์Šต

2.2 ๊ณ ๊ธ‰ SQL๊ณผ ์ธ๋ฑ์Šค ์ตœ์ ํ™”

PostgreSQL์—์„œ ๊ธฐ๋ณธ SQL์„ ์ตํ˜”๋‹ค๋ฉด, ์ด์ œ ๋” ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๊ณ ๊ธ‰ SQL ๊ธฐ๋ฒ•์„ ๋ฐฐ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฒˆ ๊ธ€์—์„œ๋Š” JOIN, ์„œ๋ธŒ์ฟผ๋ฆฌ, ์œˆ๋„์šฐ ํ•จ์ˆ˜ ๋“ฑ ๊ณ ๊ธ‰ SQL ๊ธฐ๋Šฅ๊ณผ ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•œ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


2.2.1 ๊ณ ๊ธ‰ SQL ๊ฐœ์š”

SQL์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋ฉด ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์กฐํšŒํ•˜๊ณ ,
๋ณต์žกํ•œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ํšจ๊ณผ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… ์ด๋ฒˆ ๊ธ€์—์„œ ๋‹ค๋ฃฐ ๋‚ด์šฉ

๐Ÿ”น JOIN (์กฐ์ธ)๊ณผ ์„œ๋ธŒ์ฟผ๋ฆฌ
๐Ÿ”น ์œˆ๋„์šฐ ํ•จ์ˆ˜(Window Functions)
๐Ÿ”น ์ธ๋ฑ์Šค(Index) ํ™œ์šฉ ๋ฐ ์ตœ์ ํ™”
๐Ÿ”น ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ณ„ํš ๋ถ„์„ (EXPLAIN ANALYZE)


2.2.2 JOIN๊ณผ ์„œ๋ธŒ์ฟผ๋ฆฌ ํ™œ์šฉ

๋ฐ˜์‘ํ˜•

PostgreSQL์—์„œ๋Š” JOIN(์กฐ์ธ) ์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์„œ๋ธŒ์ฟผ๋ฆฌ(Subquery) ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”น INNER JOIN (๋‚ด๋ถ€ ์กฐ์ธ)

INNER JOIN์€ ๋‘ ํ…Œ์ด๋ธ”์—์„œ ๊ณตํ†ต๋œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

SELECT users.name, orders.amount
FROM users
INNER JOIN orders ON users.id = orders.user_id;

โœ… users ํ…Œ์ด๋ธ”๊ณผ orders ํ…Œ์ด๋ธ”์„ id์™€ user_id ๊ธฐ์ค€์œผ๋กœ ์กฐ์ธ

๐Ÿ”น LEFT JOIN (์™ผ์ชฝ ์กฐ์ธ)

LEFT JOIN์€ ์™ผ์ชฝ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์ผ์น˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ NULL์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

๐Ÿ”น ์„œ๋ธŒ์ฟผ๋ฆฌ (Subquery) ํ™œ์šฉ

์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ์ฟผ๋ฆฌ ์•ˆ์—์„œ ๋˜ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

SELECT name, email 
FROM users 
WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);

โœ… 100๋‹ฌ๋Ÿฌ ์ด์ƒ ์ฃผ๋ฌธํ•œ ์‚ฌ์šฉ์ž๋งŒ ์กฐํšŒ


2.2.3 ์œˆ๋„์šฐ ํ•จ์ˆ˜(Window Functions)

์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” ํ–‰(row) ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ๋ˆ„์  ํ•ฉ๊ณ„, ์ˆœ์œ„, ์ด๋™ ํ‰๊ท  ๋“ฑ์„ ๊ณ„์‚ฐํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”น RANK()์™€ DENSE_RANK()

RANK()์™€ DENSE_RANK()๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํŠน์ • ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜๊ณ  ์ˆœ์œ„๋ฅผ ๋งค๊น๋‹ˆ๋‹ค.

SELECT name, amount,
       RANK() OVER (ORDER BY amount DESC) AS ranking,
       DENSE_RANK() OVER (ORDER BY amount DESC) AS dense_ranking
FROM orders;

๐Ÿ”น SUM() OVER()๋ฅผ ํ™œ์šฉํ•œ ๋ˆ„์  ํ•ฉ๊ณ„

SUM() OVER()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ๊ทธ๋ฃน ๋‚ด์—์„œ ๋ˆ„์  ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SELECT name, amount, 
       SUM(amount) OVER (PARTITION BY user_id ORDER BY created_at) AS running_total
FROM orders;

โœ… PARTITION BY๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ณ„ ๋ˆ„์  ํ•ฉ๊ณ„๋ฅผ ๊ณ„์‚ฐ


2.2.4 ์ธ๋ฑ์Šค(Index) ํ™œ์šฉ ๋ฐ ์ตœ์ ํ™”

๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ธ๋ฑ์Šค๊ฐ€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.
PostgreSQL์—์„œ๋Š” B-TREE, HASH, GIN, GiST, BRIN ๋“ฑ ๋‹ค์–‘ํ•œ ์ธ๋ฑ์Šค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”น ๊ธฐ๋ณธ B-TREE ์ธ๋ฑ์Šค ์ƒ์„ฑ

PostgreSQL์—์„œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธ๋ฑ์Šค๋Š” B-TREE ์ธ๋ฑ์Šค์ž…๋‹ˆ๋‹ค.

CREATE INDEX idx_users_email ON users(email);

โœ… email ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ฒ€์ƒ‰ ์†๋„๋ฅผ ํ–ฅ์ƒ

๐Ÿ”น HASH ์ธ๋ฑ์Šค (๊ณ ์œ  ๊ฐ’ ๊ฒ€์ƒ‰ ์ตœ์ ํ™”)

ํ•ด์‹œ ์ธ๋ฑ์Šค๋Š” ๊ณ ์œ ํ•œ ๊ฐ’ ๊ฒ€์ƒ‰์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

CREATE INDEX idx_users_id ON users USING HASH (id);

โœ… USING HASH๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์‹œ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑ

๐Ÿ”น GIN ์ธ๋ฑ์Šค (JSON, ๋ฐฐ์—ด ๊ฒ€์ƒ‰ ์ตœ์ ํ™”)

PostgreSQL์€ JSON, ๋ฐฐ์—ด ๋“ฑ์˜ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ํšจ์œจ์ ์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด GIN ์ธ๋ฑ์Šค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

CREATE INDEX idx_users_json ON users USING GIN (jsonb_column);

โœ… JSONB ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ


2.2.5 EXPLAIN ANALYZE๋ฅผ ํ™œ์šฉํ•œ ์ฟผ๋ฆฌ ์ตœ์ ํ™”

PostgreSQL์—์„œ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ๋ถ„์„ํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๋ ค๋ฉด EXPLAIN ANALYZE๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”น ์‹คํ–‰ ๊ณ„ํš ํ™•์ธ (EXPLAIN)

EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

โœ… ์‹คํ–‰ ๊ณ„ํš์„ ํ™•์ธํ•˜์—ฌ ์ธ๋ฑ์Šค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธ

๐Ÿ”น ์‹คํ–‰ ์‹œ๊ฐ„ ๋ถ„์„ (EXPLAIN ANALYZE)

EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

โœ… ์‹คํ–‰ ์‹œ๊ฐ„๊ณผ ์‹ค์ œ ์„ฑ๋Šฅ์„ ๋ถ„์„ํ•˜์—ฌ ์ฟผ๋ฆฌ ์ตœ์ ํ™” ๊ฐ€๋Šฅ


2.2.6 ๊ฒฐ๋ก : ๊ณ ๊ธ‰ SQL์„ ํ™œ์šฉํ•œ ์„ฑ๋Šฅ ์ตœ์ ํ™”

โœ… JOIN๊ณผ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์กฐ์ž‘ ๊ฐ€๋Šฅ
โœ… ์œˆ๋„์šฐ ํ•จ์ˆ˜(Window Functions)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ•๋ ฅํ•œ ๋ฐ์ดํ„ฐ ๋ถ„์„ ๊ธฐ๋Šฅ ์ œ๊ณต
โœ… ์ธ๋ฑ์Šค(Index)๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ฉด ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋จ
โœ… EXPLAIN ANALYZE๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ ๊ณ„ํš์„ ๋ถ„์„ํ•˜๊ณ  ์ตœ์ ํ™” ๊ฐ€๋Šฅ

์ด์ œ PostgreSQL์—์„œ ๊ณ ๊ธ‰ SQL์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ตํ˜”์Šต๋‹ˆ๋‹ค!
๋‹ค์Œ ๊ธ€์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜๊ณผ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿš€


๐Ÿ”Ž ๋‹ค์Œ ๊ธ€ ์˜ˆ๊ณ : ํŠธ๋žœ์žญ์…˜๊ณผ ๋™์‹œ์„ฑ ์ œ์–ด

๐Ÿ“Œ ๋‹ค์Œ ํŽธ: 2.3 ํŠธ๋žœ์žญ์…˜๊ณผ ๋™์‹œ์„ฑ ์ œ์–ด


์ด์ œ PostgreSQL์˜ ๊ณ ๊ธ‰ SQL๊ณผ ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ๋Œ€ํ•œ ๊ธ€์ด ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!
๋‹ค์Œ ๊ธ€์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜๊ณผ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿš€๐Ÿ˜Š

๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
ยซ   2025/03   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
๊ธ€ ๋ณด๊ด€ํ•จ
๋ฐ˜์‘ํ˜•