About
home
Tmax OpenSQL
home
๐Ÿ’Ž

19. PostgreSQL์˜ Parallel Query (2)

์ž‘์„ฑ์ž
JSW

Reminder

PostgreSQL์˜ Parallel Query์— ๋Œ€ํ•ด ์ด์–ด์„œ ์ด์•ผ๊ธฐ ํ•˜๊ธฐ์— ์•ž์„œ ์ง€๋‚œ ์ฑ•ํ„ฐ์—์„œ ์ด์•ผ๊ธฐ ํ–ˆ๋˜ ๋‚ด์šฉ์„ ์š”์•ฝํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
Parallel Query ์‹คํ–‰ ๊ณ„ํš์—๋Š” Gather ๋˜๋Š” Gather Merge ๋…ธ๋“œ๊ฐ€ ์žˆ๊ณ , ์ด ๋…ธ๋“œ์—๋Š” ํ•ญ์ƒ ํ•œ ๊ฐœ์˜ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์ธ ์งˆ์˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋˜ ํ”„๋กœ์„ธ์Šค(Leader Worker)๊ฐ€ Gather ๋˜๋Š” Gather Merge ๋…ธ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด ์‹คํ–‰ ๊ณ„ํš์—์„œ ์ œ๊ณตํ•œ Parallel Worker ๊ฐœ์ˆ˜๋งŒํผ Background Process ํ• ๋‹น์„ ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ• ๋‹น๋œ Parallel Worker๋Š” Gather์˜ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์„ ๋ฐ›์•„์„œ ๋ณ‘๋ ฌ๋กœ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Parallel Query ์‹คํ–‰ ๊ณ„ํš์„ ๋งŒ๋“ค ๋•Œ์—๋Š” Parallel Safety ๊ทœ์น™์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. Parallel Query ์‹คํ–‰ ๊ณ„ํš์€ Parallel Safe ๋˜๋Š” Parallel Restricted์ธ ๋…ธ๋“œ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•˜๋ฉฐ, Gather์˜ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์€ Parallel Safe์ธ ๋…ธ๋“œ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CTE๋‚˜ DML๊ณผ ๊ฐ™์€ Parallel Unsafeํ•œ ๋…ธ๋“œ๊ฐ€ ํ•„์š”ํ•œ Path๋Š” Parallel Query ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ง€๋‚œ ์ฑ•ํ„ฐ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Overview

์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ๋Š” Parallel Query์˜ ์‹ค์ œ ์ˆ˜ํ–‰ ๊ณผ์ •์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. Leader Worker๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” Gather ๋…ธ๋“œ์—์„œ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ค‘์ ์ ์œผ๋กœ ๋ง์”€ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

Shared Context for Parallel Query

ํ˜น์ž๋Š” ์งˆ์˜๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ˆ˜ํ–‰ํ•  ์‹คํ–‰ ๊ณ„ํš์„ Parallel Worker์—๊ฒŒ ๊ณต์œ ํ•˜๊ณ  Leader Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๊ณต์œ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•๋งŒ ๋งˆ๋ จ๋œ๋‹ค๋ฉด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ƒ์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. PostgreSQL์˜ Parallel Worker๋Š” ์ „๋‹ฌ ๋ฐ›์€ ์‹คํ–‰ ๊ณ„ํš์„ Executor Framework์— ๊ทธ๋Œ€๋กœ ์ˆ˜ํ–‰ ์‹œํ‚ค๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ์œผ๋ฉฐ, Executor๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์œ„ํ•ด์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•„์š”๋กœ ํ•˜๋Š” ์ •๋ณด๋“ค์„ Leader Worker๊ฐ€ Parallel Worker์—๊ฒŒ ์ „๋‹ฌํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด EXPLAIN ANALYZE ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•œ ์งˆ์˜์˜ ๋Ÿฐํƒ€์ž„ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ์•Œ๊ณ  ์‹ถ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, Parallel Worker๋Š” ๊ฐ์ž ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์ˆ˜์ง‘ํ•œ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ Leader Worker์—๊ฒŒ ๊ณต์œ ํ•˜๊ณ , Leader Worker๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์˜ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ์ง‘๊ณ„ํ•˜์—ฌ ๋ณด์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๋ฉด, ์งˆ์˜์— ์‚ฌ์šฉ๋˜๋Š” ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜(Bind Variable)์€ Executor์˜ ๋Ÿฐํƒ€์ž„ ์ตœ์ƒ์œ„ ์ปจํ…์ŠคํŠธ์ธ QueryDesc์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”๋ฐ, ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ Gather์˜ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์—์„œ๋„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด Parallel Worker์—๊ฒŒ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜๋ฅผ ๊ณต์œ ํ•ด์•ผ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๋“ฏ ์งˆ์˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•„์š”๋กœ ํ•˜๋Š” ์ •๋ณด๋Š” ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. PostgreSQL์—์„œ๋Š” Leader Worker์™€ Parallel Worker ์‚ฌ์ด์— ๊ณต์œ ํ•ด์•ผ ํ•˜๋Š” ์ •๋ณด๋ฅผ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ณต์œ ํ•˜์—ฌ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. Leader Worker๋Š” ๋™์  ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ(Dynamic Shared Memory) ์„ธ๊ทธ๋จผํŠธ ํ• ๋‹น์„ ์š”์ฒญํ•˜๊ณ  ํ•ด๋‹น ์„ธ๊ทธ๋จผํŠธ์— ๊ณต์œ  ์ปจํ…์ŠคํŠธ๋ฅผ ์ง๋ ฌํ™”ํ•˜์—ฌ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
Leader Worker๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๊ณต์œ  ์ปจํ…์ŠคํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
Shared Context Entry
Shared Memory Lookup Key
Description
Sub-plan
PARALLEL_KEY_PLANNEDSTMT
Parallel Worker๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž์‹ ์‹คํ–‰ ๊ณ„ํš. ํŠธ๋ฆฌ ํ˜•ํƒœ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์ง๋ ฌํ™” ํ•˜์—ฌ ๊ณต์œ ํ•จ.
Bind Parameter List
PARALLEL_KEY_PARAMLISTINFO
์งˆ์˜์— ํฌํ•จ๋œ ๋ฐ”์ธ๋“œ ๋ณ€์ˆ˜ ์ •๋ณด.
Instrumentation
PARALLEL_KEY_INSTRUMENTATION
Executor ๋Ÿฐํƒ€์ž„ ํ†ต๊ณ„ ์ •๋ณด. ๊ฐ Parallel Worker๊ฐ€ ์ˆ˜์ง‘ํ•˜๊ณ , Leader Worker๊ฐ€ ์ง‘๊ณ„ํ•จ.
Buffer Usage
PARALLEL_KEY_BUFFER_USAGE
Parallel Worker๊ฐ€ ์‚ฌ์šฉํ•œ Buffer Cache ์‚ฌ์šฉ๋Ÿ‰ ์ •๋ณด.
WAL Usage
PARALLEL_KEY_WAL_USAGE
Parallel Worker๊ฐ€ ์‚ฌ์šฉํ•œ WAL ์‚ฌ์šฉ๋Ÿ‰ ์ •๋ณด.
JIT Instrumentation
PARALLEL_KEY_JIT_INSTRUMENTATION
JIT Compilation ๊ด€๋ จ ํ†ต๊ณ„ ์ •๋ณด.
Tuple Queue
PARALLEL_KEY_TUPLE_QUEUE
Parallel Worker๊ฐ€ Leader Worker์—๊ฒŒ ๊ฒฐ๊ณผ๋ฌผ์„ ์ „๋‹ฌํ•˜๋Š” Message Queue.
Query Text
PARALLEL_KEY_QUERY_TEXT
์ˆ˜ํ–‰ ์ค‘์ธ ์งˆ์˜
DSA
PARALLEL_KEY_DSA
Leader Worker์™€ Parallel Worker๊ฐ€ Executor ์ˆ˜ํ–‰ ์ค‘์— ๊ณต์œ ํ•  ๊ฐ€๋ณ€ ๊ธธ์ด์˜ ์ •๋ณด๋ฅผ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งˆ๋ จํ•ด ๋†“์€ ๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๊ณต๊ฐ„
Fixed Parallel Executor State
PARALLEL_KEY_EXECUTOR_FIXED
๊ธฐํƒ€ Executor ์ƒํƒœ ์ •๋ณด
Parallel Aware Plan Nodeโ€™s Context
๊ฐ Plan Node์˜ ID
์‹คํ–‰ ๊ณ„ํš์— ํฌํ•จ๋œ Parallel Aware ํ•œ ๋…ธ๋“œ๊ฐ€ ๊ณต์œ ํ•ด์•ผ ํ•˜๋Š” ์ปจํ…์ŠคํŠธ. ํ‚ค๋Š” ์ž์‹ ์˜ Plan Node ID๋กœ ๋“ฑ๋กํ•จ.
์œ„์™€ ๊ฐ™์€ High-level์˜ ์ •๋ณด ์™ธ์—๋„ ๊ฐ Parallel Worker๊ฐ€ ์งˆ์˜ ์ˆ˜ํ–‰์— ํ•„์š”ํ•œ ์ž์ž˜ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์ •๋ณด๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์ •๋ณด๋“ค์€ ์ด ํฌ์ŠคํŒ…์—์„  ๋‚˜์—ด ํ•˜์ง€๋Š” ์•Š๊ฒ ์ง€๋งŒ, ๊ถ๊ธˆํ•˜์‹  ๋…์ž๋Š” ๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€ ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
Leader Worker๊ฐ€ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ๊ณต์œ  ์ปจํ…์ŠคํŠธ ์—”ํŠธ๋ฆฌ๋ฅผ ํ• ๋‹นํ•œ ํ›„ Parallel Worker๊ฐ€ ํ•ด๋‹น ์—”ํŠธ๋ฆฌ๋ฅผ ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ ์—”ํŠธ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. PostgreSQL์—์„œ๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋œ ์—”ํŠธ๋ฆฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก Lookup ํ‚ค(Key)๋ฅผ Table of Content(TOC)์— ๊ฐ™์ด ๋“ฑ๋กํ•ด์ค๋‹ˆ๋‹ค. Leader Worker๊ฐ€ ์—”ํŠธ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋ฉด์„œ 64-bit ์ •์ˆ˜๋กœ ๋œ ํ‚ค๋ฅผ ๋“ฑ๋กํ•ด์ฃผ๊ณ , Parallel Worker๋Š” Lookup ํ•จ์ˆ˜์— ํ•„์š”๋กœ ํ•˜๋Š” ์—”ํŠธ๋ฆฌ์˜ ํ‚ค๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์—”ํŠธ๋ฆฌ์˜ ์œ„์น˜๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค (C++ Boost Library๊ฐ€ ์ต์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž๋Š” boost::interprocess::managed_shared_memory ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋– ์˜ฌ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค). ์•„๋ž˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค.
/* Parallel Worker์™€ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ์œ„ํ•œ Magic Number */ #define PARALLEL_KEY_EXECUTOR_FIXED UINT64CONST(0xE000000000000001) #define PARALLEL_KEY_PLANNEDSTMT UINT64CONST(0xE000000000000002) #define PARALLEL_KEY_PARAMLISTINFO UINT64CONST(0xE000000000000003) #define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xE000000000000004) #define PARALLEL_KEY_TUPLE_QUEUE UINT64CONST(0xE000000000000005) #define PARALLEL_KEY_INSTRUMENTATION UINT64CONST(0xE000000000000006) #define PARALLEL_KEY_DSA UINT64CONST(0xE000000000000007) #define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xE000000000000008) #define PARALLEL_KEY_JIT_INSTRUMENTATION UINT64CONST(0xE000000000000009) #define PARALLEL_KEY_WAL_USAGE UINT64CONST(0xE00000000000000A) ... /* Buffer Usage๋ฅผ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹นํ•˜๋ฉฐ key ๋“ฑ๋ก */ bufusage_space = shm_toc_allocate(pcxt->toc, mul_size(sizeof(BufferUsage), pcxt->nworkers)); shm_toc_insert(pcxt->toc, PARALLEL_KEY_BUFFER_USAGE, bufusage_space); pei->buffer_usage = bufusage_space; /* WAL Usage๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ key ๋“ฑ๋ก */ walusage_space = shm_toc_allocate(pcxt->toc, mul_size(sizeof(WalUsage), pcxt->nworkers)); shm_toc_insert(pcxt->toc, PARALLEL_KEY_WAL_USAGE, walusage_space); pei->wal_usage = walusage_space;
C
๋ณต์‚ฌ
DSM ๊ณต๊ฐ„์€ ๋™์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ธฐ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌํ•˜๊ณ  ๊ทธ์— ๋งž์ถฐ DSM ์„ธ๊ทธ๋จผํŠธ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ DSM ์„ธ๊ทธ๋จผํŠธ์— ์—”ํŠธ๋ฆฌ๋ฅผ ํ• ๋‹นํ•  ๋•Œ์—๋Š” ์„ธ๊ทธ๋จผํŠธ ๋‚ด ๋ฒ„ํผ์˜ ์˜คํ”„์…‹ ๊ฐ’๋งŒ ์กฐ์ •ํ•˜๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹คํ–‰ ๊ณ„ํš์˜ PlannedStmt์™€ ๊ฐ™์ด ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ๋Š” ์—”ํŠธ๋ฆฌ๋ฅผ ์ผ๋ฐ˜์ ์ธ Heap ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ํ• ๋‹นํ•˜๋“ฏ์ด DSM ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด, ํŠธ๋ฆฌ ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ ํฌ์ธํ„ฐ ๊ฐ’๋“ค์„ ๋งค๋ฒˆ ๊ต์ฒดํ•ด์ค˜์•ผ ํ•˜๋Š” ์–ด๋ ค์›€์ด ์ƒ๊น๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์–ด๋ ค์›€์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด PostgreSQL์—์„œ๋Š” ํŠธ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด ํƒ€์ž…์œผ๋กœ ์ง๋ ฌํ™” ํ•˜์—ฌ DSM ๊ณต๊ฐ„์— ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ง๋ ฌํ™” ํ•œ ํŠธ๋ฆฌ๋ฅผ Parallel Worker๋Š” ์—ญ์ง๋ ฌํ™” ํ•˜์—ฌ ์ž์‹ ์˜ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ๋‹ค์‹œ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ ๋ณต์›ํ•˜๋Š” ์ž‘์—…์„ ๊ฑฐ์ณ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
๋˜ ํ•˜๋‚˜ ์ž์„ธํžˆ ๋ด์•ผ ํ•  ๊ฒƒ์€ Tuple Queue์ž…๋‹ˆ๋‹ค. Leader Worker๋Š” Parallel Worker์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„ ์ƒ์œ„ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ Parallel Worker์—๊ฒŒ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์„ Message Queue๋ฅผ ๊ฐ Parallel Worker ๋งˆ๋‹ค ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. Leader Worker๋Š” ์ž์‹ ์˜ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ์— Message Queue ๋ฒ„ํผ๋ฅผ ์ฐธ์กฐํ•˜๋Š” Message Queue ํ•ธ๋“ค์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. Message Queue ๋ฒ„ํผ๋Š” DSM ๊ณต๊ฐ„์— Parallel Worker ๊ฐœ์ˆ˜๋ฅผ ๊ณฑํ•˜์—ฌ ์—ฐ์†๋œ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•˜๊ณ , ๊ฐ Message Queue ํ•ธ๋“ค์— ๋ฒ„ํผ์˜ ์˜คํ”„์…‹์„ ์˜ฎ๊ฒจ๊ฐ€๋ฉฐ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ค์–ด ๋†“์Šต๋‹ˆ๋‹ค. Parallel Worker๋Š” Executor์—์„œ Client์— ๊ฒฐ๊ณผ๋ฌผ์„ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ์กฐ์ฒด์ธ DestReceiver ๋ฅผ ์ž์‹ ์˜ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹นํ•˜๊ณ  DSM ๊ณต๊ฐ„์— ํ• ๋‹น๋œ ์ž์‹ ์˜ Message Queue ๋ฒ„ํผ๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ์„ค์ •ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฌผ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

Launching Parallel Workers

Parallel Worker์™€ ๊ณต์œ ํ•  ์ •๋ณด๋ฅผ DSM ์„ธ๊ทธ๋จผํŠธ์— ํ• ๋‹นํ–ˆ์œผ๋ฉด Parallel Worker๋ฅผ ์‹œ์ž‘ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Parallel Worker๋Š” Background Process๋กœ ์‹คํ–‰๋˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ PostgreSQL์—์„œ Background Process๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์„ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Leader Worker๊ฐ€ Background Process๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜ ์Šคํ…์„ ๋”ฐ๋ผ๊ฐ‘๋‹ˆ๋‹ค.
1.
Background Process์˜ ์ƒํƒœ ์ •๋ณด๋ฅผ ๋‹ด์€ ์Šฌ๋กฏ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
a.
๊ฐ ์Šฌ๋กฏ์—๋Š” Background Process์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋Š”๋ฐ, ํ˜„์žฌ ์†Œ๊ฐœํ•˜๋Š” ๋กœ์ง์—์„œ๋Š” ์•„๋ž˜ ํ•„๋“œ๋งŒ ์ค‘์š”ํ•˜๊ฒŒ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
โ€ข
in_use: Background Process๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋ž˜๊ทธ
โ€ข
bgw_function_name: Background Process๊ฐ€ ํ˜ธ์ถœํ•  Entrypoint ํ•จ์ˆ˜ ์ด๋ฆ„
โ€ข
pid: Background Process์˜ ํ”„๋กœ์„ธ์Šค ์•„์ด๋””
2.
Leader Worker๋Š” ์Šฌ๋กฏ์„ ์ˆœํšŒํ•˜๋ฉฐ in_use ํ”Œ๋ž˜๊ทธ๊ฐ€ false ๊ฐ’์ธ ๊ณต๊ฐ„์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
3.
์ฐพ์€ ์Šฌ๋กฏ์˜ ํ•„๋“œ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
a.
bgw_function_name = ParallelWorkerMain
b.
pid = InvalidPID (PostMaster๊ฐ€ ์‹œ์ž‘๋˜์ง€ ์•Š์€ Background Process๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•)
c.
in_use = true
4.
PostMaster์—๊ฒŒ PMSIGNAL_BACKGROUND_WORKER_CHANGE ์‹œ๊ทธ๋„์„ ๋ณด๋‚ด Background Process์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.
5.
PostMaster๋Š” Background Process ์Šฌ๋กฏ์„ ์ˆœํšŒํ•˜๋ฉฐ ์‹œ์ž‘๋˜์ง€ ์•Š์€ Process๋ฅผ ์ฐพ์•„ ์‹คํ–‰์‹œ์ผœ ์ค๋‹ˆ๋‹ค.
Optimizer๊ฐ€ ์ƒ์„ฑํ•œ ์‹คํ–‰ ๊ณ„ํš์— ๋ช…์‹œ๋œ Parallel Worker ์ˆ˜๋งŒํผ Background Process๋ฅผ ํ• ๋‹น์‹œํ‚ค๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์œ„ ๋ฐฉ์‹ ๋Œ€๋กœ ๋ฌธ์ œ ์—†์ด ์ˆ˜ํ–‰๋˜์ง€๋งŒ ๋™์‹œ์— ๋„ˆ๋ฌด ๋งŽ์€ Parallel Worker๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ์ˆ˜์šฉํ–ˆ๋‹ค๊ฐ€๋Š” ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํ“จํŒ… ์ž์›์„ ์ดˆ๊ณผํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒํ•˜์—ฌ ๋ฌธ์ œ๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Ÿฐ ์ƒํ™ฉ์„ ์šฐ๋ คํ•˜์—ฌ PostgreSQL์—์„œ๋Š” max_parallel_worker ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋งˆ๋ จํ–ˆ์Šต๋‹ˆ๋‹ค. Leader Worker๊ฐ€ Parallel Worker๋ฅผ ํ• ๋‹นํ•˜๋Ÿฌ ํ•จ์ˆ˜์— ์ง„์ž…ํ–ˆ์„ ๋•Œ ํ˜„์žฌ ์ƒ์„ฑํ•œ Parallel Worker ๊ฐœ์ˆ˜๊ฐ€ max_parallel_worker๋ฅผ ์ดˆ๊ณผํ•œ๋‹ค๋ฉด ๋” ์ด์ƒ ํ• ๋‹น์„ ์‹œ๋„ํ•˜์ง€ ์•Š๊ณ  ํ• ๋‹นํ•œ ๊ฐœ์ˆ˜์— ๋งŒ์กฑํ•˜๋ฉฐ ์ˆ˜ํ–‰์„ ์ด์–ด๊ฐ‘๋‹ˆ๋‹ค. ๋งŒ์•ฝ Parallel Worker๋ฅผ ํ• ๋‹นํ•˜์ง€ ๋ชป ํ–ˆ์„ ๊ฒฝ์šฐ Leader Worker๊ฐ€ ํ˜ผ์ž์„œ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋งˆ๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๊ฒฝ์šฐ Optimizer๊ฐ€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์— ์ ํ•ฉํ•˜๊ฒŒ ์ƒ์„ฑํ•œ ์‹คํ–‰ ๊ณ„ํš์„ Leader Worker ํ˜ผ์ž์„œ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋•Œ์— ๋”ฐ๋ผ ์ƒ๋‹นํžˆ ํฐ ๋น„ํšจ์œจ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Receiving Tuples

๋งˆ์ง€๋ง‰์œผ๋กœ Leader Worker๊ฐ€ Parallel Worker๋กœ๋ถ€ํ„ฐ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„์˜ค๋Š” ๊ณผ์ •์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•ž์„  ์„ค๋ช…์—์„œ DSM ์„ธ๊ทธ๋จผํŠธ์— Leader Worker๊ฐ€ Parallel Worker ๊ฐœ์ˆ˜๋งŒํผ Tuple Queue๋ฅผ ํ• ๋‹นํ•œ๋‹ค๊ณ  ๋ง์”€ ๋“œ๋ ธ์Šต๋‹ˆ๋‹ค. Parallel Worker๋Š” DSM ์„ธ๊ทธ๋จผํŠธ์—์„œ ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋œ Tuple Queue๋ฅผ ๋ฐ›์•„์™€ ์ž์‹ ์˜ Executor Frame๊ณผ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๊ฒฐํ•ฉํ•œ Tuple Queue์— ์‚ฝ์ž…ํ•˜๋ฉด Leader Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
Leader Worker์˜ ์ž…์žฅ์—์„œ๋Š” ์—ฌ๋Ÿฌ Parallel Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด๋‚ด์–ด Tuple Queue๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ Gather ๋…ธ๋“œ์˜ ๊ฒฝ์šฐ ์ˆœ์„œ์™€ ์ƒ๊ด€ ์—†์ด ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ ๊ฒฐ๊ณผ๋ฌผ์„ ๊บผ๋‚ด์–ด ์ƒ์œ„ ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์— ์ˆจ๊ฒจ์ง„ ์ตœ์ ํ™” ํฌ์ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Leader Worker๋Š” ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ Tuple Queue๋ฅผ ์ˆœํšŒํ•˜๋˜ Parallel Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด๋‚ด๊ธฐ ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด 4๊ฐœ์˜ Parallel Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด๋‚ด๊ณ  ์žˆ์„ ๋•Œ Leader Worker๋Š” 0๋ฒˆ Queue๋ถ€ํ„ฐ ์ˆœํšŒ๋ฅผ ํ•˜๋ฉฐ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„๊ฐ€๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ 0๋ฒˆ Queue์— ๊ฒฐ๊ณผ๋ฌผ์ด ๊ณต์œ ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด Leader Worker๋Š” ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค์Œ Queue๋กœ ๊ฐ€์„œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.
Tuple์„ ์ƒ์„ฑํ•œ Tuple Queue๋ฅผ ์ฐพ์•„ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ›์•„๊ฐ‘๋‹ˆ๋‹ค
๋งŒ์•ฝ 1๋ฒˆ Queue์— ๊ฒฐ๊ณผ๋ฌผ์ด ์žˆ์–ด์„œ ํ•ด๋‹น ํŠœํ”Œ์„ ์ƒ์œ„ ์‹คํ–‰ ๊ณ„ํš์œผ๋กœ ์ „๋‹ฌํ•˜๊ณ  ๋‹ค์‹œ ๋Œ์•„์˜ค๊ฒŒ ๋˜๋ฉด ๋‹ค์‹œ 0๋ฒˆ Queue๋ถ€ํ„ฐ ์ˆœํšŒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ 1๋ฒˆ Queue๋ถ€ํ„ฐ ๊ฒฐ๊ณผ๋ฌผ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฌธํ–ˆ๋˜ Tuple Queue์— ๋” ์ด์ƒ Tuple์ด ์ œ ์‹œ๊ฐ„์— ๋‚˜์˜ค์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ์ด๋ฅผ ๋ฐ˜๋ณตํ•˜์—ฌ Tuple์„ ๋ฐ›์•„๊ฐ‘๋‹ˆ๋‹ค.์ด๋ ‡๊ฒŒ ๋กœ์ง์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š” ์ด์œ ๋Š” ์ œ์ผ ๋น ๋ฅธ ์†๋„๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” Parallel Worker ๊ธฐ์ค€์œผ๋กœ ๊ฒฐ๊ณผ๋ฌผ์„ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ ๋‹ค๋ฅธ Parallel Worker์—๊ฒŒ ๋งˆ์ € ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋‹ค์‹œ ๋Œ์•„์™”์„ ๋•Œ๋Š” ๋ฐฉ๋ฌธํ–ˆ๋˜ Tuple Queue์—์„œ Tuple์ด ์†Œ์ง„๋  ๋•Œ๊นŒ์ง€ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ Parallel Worker๊ฐ€ ๋งˆ์ € ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜์—ฌ Tuple์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ํšจ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
๋งŒ์•ฝ Queue๋ฅผ ๋ชจ๋‘ ์ˆœํšŒํ–ˆ์ง€๋งŒ ๋ชจ๋“  Parallel Worker๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ์ „๋‹ฌํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด Leader Worker์—๊ฒŒ๋Š” ๋‘ ๊ฐ€์ง€ ์„ ํƒ์ด ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” Leader Worker ๋ณธ์ธ์ด ์ง์ ‘ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” Parallel Worker ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋จผ์ € ๋๋‚ด๋Š” Worker๊ฐ€ ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์„ ํƒ์€ parallel_leader_participation ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ผœ์ ธ ์žˆ๋Š” ๊ฒฝ์šฐ ํ™œ์„ฑํ™”๋˜๊ณ , ๋‘ ๋ฒˆ์งธ ์„ ํƒ์€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๊บผ์ ธ ์žˆ์„ ๊ฒฝ์šฐ ํ™œ์„ฑํ™” ๋ฉ๋‹ˆ๋‹ค.

Conclusion

์˜ค๋Š˜ ์†Œ๊ฐœํ•œ Parallel Query์˜ ์‹คํ–‰ ๋ถ€๋ถ„์„ ์š”์•ฝํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
โ€ข
Parallel Query์— ํ•„์š”ํ•œ ๊ณต์šฉ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด Leader Worker๋Š” ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ(DSM) ์„ธ๊ทธ๋จผํŠธ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ๊ฐ์ข… ์ •๋ณด๋ฅผ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค.
โ€ข
Leader Worker๊ฐ€ Parallel Worker๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด Background Worker Slot์„ ์ˆœํšŒํ•˜์—ฌ ๊ฐ€์šฉ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ€์šฉ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฐพ์œผ๋ฉด ์‹คํ–‰ํ•  Entrypoint ํ•จ์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ  PostMaster์—๊ฒŒ ์‹œ๊ทธ๋„์„ ๋ณด๋‚ด Background Worker๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
Background Process๊ฐ€ ์ƒ์„ฑํ•œ ํŠœํ”Œ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๋ฉ”์‹œ์ง€ ํ๋ฅผ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๋ชจ๋“  ๋ฉ”์‹œ์ง€ ํ์— ์ƒ์„ฑ๋œ ํŠœํ”Œ์ด ์—†๋Š” ๊ฒฝ์šฐ, parallel_leader_participation ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ผœ์ ธ ์žˆ์œผ๋ฉด Leader Worker๊ฐ€ ์ง์ ‘ ์ž์‹ ์‹คํ–‰ ๊ณ„ํš์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ํŠœํ”Œ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
๋‹ค์Œ Parallel Query ์‹œ๋ฆฌ์ฆˆ์—์„œ๋Š” Parallel Worker๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„๋ฐฐํ•˜์—ฌ ์Šค์บ” ํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์กฐ์ธ๊ณผ ์ง‘๊ณ„ํ•จ์ˆ˜์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์€ ๋ณ‘๋ ฌ๋กœ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ณ  ์˜ค๋Š˜ ํฌ์ŠคํŒ…์€ ์ด๋งŒ ๋งˆ์น˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
์ง€๊ธˆ๊นŒ์ง€ PostgreSQL์˜ Parallel Query (2)์— ๊ด€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค
PostgreSQL์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์šฉํ•œ ํŒ์„ ๊ฐ€์ง€๊ณ  ๋Œ์•„์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ์ปจํ…์ธ ๋„ ๊ธฐ๋Œ€ํ•ด์ฃผ์„ธ์š”! (์ปจํ…์ธ ๋Š” ๊ฒฉ์ฃผ ์—…๋ฐ์ดํŠธ ๋ฉ๋‹ˆ๋‹ค.)
PostgreSQL ์˜ Internal Architecture ํฌ์ŠคํŒ…์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ณด์‹œ๋ ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ํด๋ฆญํ•ด์ฃผ์„ธ์š”!

์ž์œ ๋กญ๊ฒŒ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์„ธ์š”