PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ„์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ ๊ธฐ๋ก ์ฃผ์ œ ํŒŒํ‹ฐ์…”๋‹์— ๊ด€ํ•œ ์ด์ „ ๊ธฐ์‚ฌ, ์—ฌ๊ธฐ์„œ๋Š” ๊ท€ํ•˜๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์˜ "๋ฌผ๋ฆฌ์ " ํฌ๊ธฐ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค. PostgreSQL์˜ ์„œ๋ฒ„ ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ.

์šฐ๋ฆฌ๋Š”์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค TOAST ์„ค์ • ๋ฐ ๋ฐ์ดํ„ฐ ์ •๋ ฌ. ํ‰๊ท ์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์ ˆ์•ฝํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ์ „ํ˜€ ์ˆ˜์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ์˜ ๊ฒฝํ—˜์€ ์ด์™€ ๊ด€๋ จํ•˜์—ฌ ๋งค์šฐ ์ƒ์‚ฐ์ ์ธ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฑฐ์˜ ๋ชจ๋“  ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ์ €์žฅ์€ ๋ณธ์งˆ์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„ ์ถ”๊ฐ€ โ€‹โ€‹์ „์šฉ ๊ธฐ๋ก๋œ ๋ฐ์ดํ„ฐ๋กœ ๋ณด๋ฉด. ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋Œ€์‹  ๋””์Šคํฌ์— ์“ฐ๋„๋ก ๊ฐ€๋ฅด์น  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด 200MB / s์˜ ์ ˆ๋ฐ˜ - ๊ณ ์–‘์ด ๋ฐ‘์œผ๋กœ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋น…๋ฐ์ดํ„ฐ์˜ ์ž‘์€ ๋น„๋ฐ€

์ง์—… ํ”„๋กœํ•„๋ณ„ ์šฐ๋ฆฌ์˜ ์„œ๋น„์Šค, ๊ทธ๋“ค์€ ์ •๊ธฐ์ ์œผ๋กœ ์€์‹ ์ฒ˜์—์„œ ๊ทธ์—๊ฒŒ ๋‚ ์•„๊ฐ‘๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ํŒจํ‚ค์ง€.

์ดํ›„ VLSI ๋ณตํ•ฉ์ฒด์šฐ๋ฆฌ๊ฐ€ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ๋‹ค์ค‘ ๊ตฌ์„ฑ ์š”์†Œ ์ œํ’ˆ์ด๊ณ  ์ฟผ๋ฆฌ๋Š” ์ตœ๋Œ€ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๊ฝค ์ด๋ ‡๋‹ค ๋ณต์žกํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋กœ์ง์„ ๊ฐ–์ถ˜ "๋‹ค์ค‘ ๋ณผ๋ฅจ". ๋”ฐ๋ผ์„œ ์š”์ฒญ์˜ ๊ฐ ๊ฐœ๋ณ„ ์ธ์Šคํ„ด์Šค ๋ณผ๋ฅจ์ด๋‚˜ ์šฐ๋ฆฌ์—๊ฒŒ ์ „๋‹ฌ๋˜๋Š” ๋กœ๊ทธ์˜ ๊ฒฐ๊ณผ ์‹คํ–‰ ๊ณ„ํš์€ "ํ‰๊ท ์ ์œผ๋กœ" ์ƒ๋‹นํžˆ ํฐ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.

"์›์‹œ" ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ํ…Œ์ด๋ธ” ์ค‘ ํ•˜๋‚˜์˜ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋กœ๊ทธ ํ•ญ๋ชฉ์˜ ์›๋ณธ ํ…์ŠคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

CREATE TABLE rawdata_orig(
  pack -- PK
    uuid NOT NULL
, recno -- PK
    smallint NOT NULL
, dt -- ะบะปัŽั‡ ัะตะบั†ะธะธ
    date
, data -- ัะฐะผะพะต ะณะปะฐะฒะฝะพะต
    text
, PRIMARY KEY(pack, recno)
);

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ…์ŠคํŠธ์ธ ์ผ๋ฐ˜์ ์ธ ๊ธฐํ˜ธ(๋ฌผ๋ก  ์ด๋ฏธ ์„น์…˜์ด ๊ตฌ๋ถ„๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์„น์…˜ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค). ๋•Œ๋กœ๋Š” ๊ฝค ๋ฐฉ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

PG์— ์žˆ๋Š” ํ•œ ๋ ˆ์ฝ”๋“œ์˜ "๋ฌผ๋ฆฌ์ " ํฌ๊ธฐ๋Š” ํ•œ ํŽ˜์ด์ง€ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐจ์ง€ํ•  ์ˆ˜ ์—†์ง€๋งŒ "๋…ผ๋ฆฌ์ " ํฌ๊ธฐ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ํ•„๋“œ์— ์ฒด์  ๊ฐ’(varchar/text/bytea)์„ ์“ฐ๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ† ์ŠคํŠธ ๊ธฐ์ˆ :

PostgreSQL์€ ๊ณ ์ •๋œ ํŽ˜์ด์ง€ ํฌ๊ธฐ(์ผ๋ฐ˜์ ์œผ๋กœ 8KB)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ํŠœํ”Œ์ด ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์— ๊ฑธ์ณ ์žˆ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋งค์šฐ ํฐ ํ•„๋“œ ๊ฐ’์„ ์ง์ ‘ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ œํ•œ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ํฐ ํ•„๋“œ ๊ฐ’์€ ์—ฌ๋Ÿฌ ๋ฌผ๋ฆฌ์  ๋ผ์ธ์— ๊ฑธ์ณ ์••์ถ• ๋ฐ/๋˜๋Š” ๋ถ„ํ• ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•œ ์ฑ„ ๋ฐœ์ƒํ•˜๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋ฒ„ ์ฝ”๋“œ์— ๊ฑฐ์˜ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ TOAST๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ "์ž ์žฌ์ ์œผ๋กœ ํฐ" ํ•„๋“œ๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ "์Šฌ๋ผ์ด์‹ฑ"์ด ํฌํ•จ๋œ ์Œ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. 2KB ์„ธ๊ทธ๋จผํŠธ์˜ ๊ฐ "๋Œ€ํ˜•" ๋ ˆ์ฝ”๋“œ:

TOAST(
  chunk_id
    integer
, chunk_seq
    integer
, chunk_data
    bytea
, PRIMARY KEY(chunk_id, chunk_seq)
);

์ฆ‰, "ํฐ" ๊ฐ’์„ ๊ฐ€์ง„ ๋ฌธ์ž์—ด์„ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ data, ๊ทธ๋Ÿฌ๋ฉด ์‹ค์ œ ๋…น์Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค ๋ฉ”์ธ ํ…Œ์ด๋ธ”๊ณผ ํ•ด๋‹น PK๋ฟ๋งŒ ์•„๋‹ˆ๋ผ TOAST์™€ ํ•ด๋‹น PK๊นŒ์ง€.

TOAST ์˜ํ–ฅ๋ ฅ ๊ฐ์†Œ

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ์˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋ก์€ ์•„์ง ๊ทธ๋ ‡๊ฒŒ ํฌ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. 8KB์— ๋งž์•„์•ผ ํ•จ - ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋ˆ์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‚˜์š”?..

์ด๊ฒƒ์ด ๋ฐ”๋กœ ์†์„ฑ์ด ์šฐ๋ฆฌ์—๊ฒŒ ๋„์›€์ด ๋˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. STORAGE ํ…Œ์ด๋ธ” ์—ด์—์„œ:

  • ํ™•์žฅ ์••์ถ•๊ณผ ๋ณ„๋„ ์ €์žฅ์ด ๋ชจ๋‘ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ ํ‘œ์ค€ ์˜ต์…˜ ๋Œ€๋ถ€๋ถ„์˜ TOAST ํ˜ธํ™˜ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋จผ์ € ์••์ถ•์„ ์‹œ๋„ํ•œ ๋‹ค์Œ ํ–‰์ด ์—ฌ์ „ํžˆ ๋„ˆ๋ฌด ํฌ๋ฉด ํ…Œ์ด๋ธ” ์™ธ๋ถ€์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฉ”์ธ ์••์ถ•์€ ํ—ˆ์šฉํ•˜์ง€๋งŒ ๋ณ„๋„์˜ ์ €์žฅ์€ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์‹ค์ œ๋กœ ์ด๋Ÿฐ ์ปฌ๋Ÿผ์— ๋Œ€ํ•ด์„œ๋Š” ์—ฌ์ „ํžˆ ๋ณ„๋„์˜ ์ €์žฅ์ด ์ด๋ฃจ์–ด์ง€๊ฒ ์ง€๋งŒ, ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ, ํŽ˜์ด์ง€์— ๋งž๋„๋ก ๋ฌธ์ž์—ด์„ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒฝ์šฐ.)

์‚ฌ์‹ค, ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ณธ๋ฌธ์— ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ๋Œ€ํ•œ ์••์ถ•ํ•˜๊ณ , ์ „ํ˜€ ๋งž์ง€ ์•Š์œผ๋ฉด TOAST์— ๋„ฃ์–ด๋ณด์„ธ์š”. ์ด ์ž‘์—…์€ ๋‹ค์Œ ๋ช…๋ น ํ•˜๋‚˜๋กœ ์ฆ‰์‹œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ALTER TABLE rawdata_orig ALTER COLUMN data SET STORAGE MAIN;

ํšจ๊ณผ๋ฅผ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„์€ ๋งค์ผ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์— ์ ˆ๋Œ€์ ์ธ ์ˆ˜์น˜๋ฅผ ๋น„๊ตํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ์ƒ๋Œ€์ ์ธ ์ˆ˜์น˜๋กœ ๋น„๊ตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ž‘์€ ๋ชซ TOAST์— ์ ์–ด๋‘์—ˆ์œผ๋‹ˆ ํ›จ์”ฌ ๋” ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์—๋Š” ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๊ฐœ๋ณ„ ๋ ˆ์ฝ”๋“œ์˜ "๋ฌผ๋ฆฌ์ " ๋ณผ๋ฅจ์ด ํด์ˆ˜๋ก ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค๊ฐ€ "๋” ๋„“์–ด์ง‘๋‹ˆ๋‹ค".

์„น์…˜ ๋ณ€๊ฒฝ ์ „:

heap  = 37GB (39%)
TOAST = 54GB (57%)
PK    =  4GB ( 4%)

์„น์…˜ ๋ณ€๊ฒฝ ํ›„:

heap  = 37GB (67%)
TOAST = 16GB (29%)
PK    =  2GB ( 4%)

์‚ฌ์‹ค ์šฐ๋ฆฌ๋Š” TOAST์— ์“ฐ๊ธฐ ์‹œ์ž‘ ๋นˆ๋„๊ฐ€ 2๋ฐฐ ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค., ์ด๋Š” ๋””์Šคํฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ CPU๋„ ์–ธ๋กœ๋“œํ–ˆ์Šต๋‹ˆ๋‹ค.

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
"์“ฐ๊ธฐ"๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋””์Šคํฌ "์ฝ๊ธฐ"์—์„œ๋„ ์ž‘์•„์กŒ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ๋•Œ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ์ธ๋ฑ์Šค ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๋„ "์ฝ์–ด์•ผ"ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฏธ๋ž˜์˜ ์œ„์น˜.

PostgreSQL 11์—์„œ ์ž˜ ์‚ด ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ

PG11๋กœ ์—…๋ฐ์ดํŠธํ•œ ํ›„ TOAST๋ฅผ ๊ณ„์† "ํŠœ๋‹"ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์œผ๋ฉฐ ์ด ๋ฒ„์ „๋ถ€ํ„ฐ ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํŠœ๋‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. toast_tuple_target:

TOAST ์ฒ˜๋ฆฌ ์ฝ”๋“œ๋Š” ํ…Œ์ด๋ธ”์— ์ €์žฅ๋  ํ–‰ ๊ฐ’์ด TOAST_TUPLE_THRESHOLD ๋ฐ”์ดํŠธ(์ผ๋ฐ˜์ ์œผ๋กœ 2KB)๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. TOAST ์ฝ”๋“œ๋Š” ํ–‰ ๊ฐ’์ด TOAST_TUPLE_TARGET ๋ฐ”์ดํŠธ(๋ณ€์ˆ˜ ๊ฐ’, ์ผ๋ฐ˜์ ์œผ๋กœ 2KB) ๋ฏธ๋งŒ์ด ๋˜๊ฑฐ๋‚˜ ํฌ๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ํ…Œ์ด๋ธ”์—์„œ ํ•„๋“œ ๊ฐ’์„ ์••์ถ• ๋ฐ/๋˜๋Š” ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ "๋งค์šฐ ์งง๊ฑฐ๋‚˜" "๋งค์šฐ ๊ธธ๋‹ค"๊ณ  ํŒ๋‹จํ•˜์—ฌ ๊ฐ€๋Šฅํ•œ ์ตœ์†Œ๊ฐ’์œผ๋กœ ์ œํ•œํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

ALTER TABLE rawplan_orig SET (toast_tuple_target = 128);

์žฌ๊ตฌ์„ฑ ํ›„ ์ƒˆ๋กœ์šด ์„ค์ •์ด ๋””์Šคํฌ ๋กœ๋”ฉ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜์˜์ง€ ์•Š๋‹ค! ํ‰๊ท  ๋””์Šคํฌ ๋Œ€๊ธฐ์—ด์ด ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฝ 1.5๋ฐฐ์ด๊ณ  ๋””์Šคํฌ "์‚ฌ์šฉ ์ค‘"์€ 20%์ž…๋‹ˆ๋‹ค! ํ•˜์ง€๋งŒ ์ด๊ฒƒ์ด CPU์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์ณค์„๊นŒ์š”?

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ ์–ด๋„ ์ƒํ™ฉ์ด ๋” ์•…ํ™”๋˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ณผ๋ฅจ์œผ๋กœ๋„ ์—ฌ์ „ํžˆ ํ‰๊ท  CPU ๋กœ๋“œ๋ฅผ ๋” ๋†’์ผ ์ˆ˜ ์—†๋Š”์ง€ ํŒ๋‹จํ•˜๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. 5%.

์šฉ์–ด์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹๋ณ€๊ฒฝํ•˜๋ฉด ํ•ฉ๊ณ„๊ฐ€... ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค!

์•„์‹œ๋‹ค์‹œํ”ผ, XNUMXํŽ˜๋‹ˆ๋Š” ๋ฃจ๋ธ”์„ ์ ˆ์•ฝํ•˜๋ฉฐ ์ €์žฅ๋Ÿ‰์€ ๋Œ€๋žต 10TB/์›” ์•ฝ๊ฐ„์˜ ์ตœ์ ํ™”๋ผ๋„ ์ข‹์€ ์ด์ต์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ฌผ๋ฆฌ์  ๊ตฌ์กฐ์— ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์˜€์Šต๋‹ˆ๋‹ค. ๋ ˆ์ฝ”๋“œ ๋‚ด๋ถ€์˜ "๋ˆ„์ " ํ•„๋“œ ํ…Œ์ด๋ธ”๋งˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์ •๋ ฌ ์ด๊ฑด ๊ฐ„๋‹จํ•ด์š” ๊ฒฐ๊ณผ ๋ณผ๋ฅจ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค:

๋งŽ์€ ์•„ํ‚คํ…์ฒ˜๋Š” ๊ธฐ๊ณ„์–ด ๊ฒฝ๊ณ„์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ •๋ ฌ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 32๋น„ํŠธ x86 ์‹œ์Šคํ…œ์—์„œ ์ •์ˆ˜(์ •์ˆ˜ ์œ ํ˜•, 4๋ฐ”์ดํŠธ)๋Š” ๋ฐฐ์ •๋ฐ€๋„ ๋ถ€๋™ ์†Œ์ˆ˜์  ์ˆซ์ž(์ด์ค‘ ์ •๋ฐ€๋„ ๋ถ€๋™ ์†Œ์ˆ˜์ , 4๋ฐ”์ดํŠธ)์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 8๋ฐ”์ดํŠธ ๋‹จ์–ด ๊ฒฝ๊ณ„์— ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  64๋น„ํŠธ ์‹œ์Šคํ…œ์—์„œ๋Š” double ๊ฐ’์ด 8๋ฐ”์ดํŠธ ๋‹จ์–ด ๊ฒฝ๊ณ„์— ๋งž์ถฐ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋น„ํ˜ธํ™˜์„ฑ์˜ ๋˜ ๋‹ค๋ฅธ ์ด์œ ์ž…๋‹ˆ๋‹ค.

์ •๋ ฌ๋กœ ์ธํ•ด ํ…Œ์ด๋ธ” โ€‹โ€‹ํ–‰์˜ ํฌ๊ธฐ๋Š” ํ•„๋“œ ์ˆœ์„œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ด ํšจ๊ณผ๋Š” ๊ทธ๋‹ค์ง€ ๋ˆˆ์— ๋„์ง€ ์•Š์ง€๋งŒ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํฌ๊ธฐ๊ฐ€ ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, char(1)๊ณผ ์ •์ˆ˜ ํ•„๋“œ๋ฅผ ํ˜ผํ•ฉํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ๋‘˜ ์‚ฌ์ด์— 3๋ฐ”์ดํŠธ๊ฐ€ ๋‚ญ๋น„๋ฉ๋‹ˆ๋‹ค.

ํ•ฉ์„ฑ ๋ชจ๋ธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

SELECT pg_column_size(ROW(
  '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
, '2019-01-01'::date
));
-- 48 ะฑะฐะนั‚

SELECT pg_column_size(ROW(
  '2019-01-01'::date
, '0000-0000-0000-0000-0000-0000-0000-0000'::uuid
, 0::smallint
));
-- 46 ะฑะฐะนั‚

์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ์— ๋‘ ๊ฐœ์˜ ์ถ”๊ฐ€ ๋ฐ”์ดํŠธ๋Š” ์–ด๋””์—์„œ ์™”์Šต๋‹ˆ๊นŒ? ๊ฐ„๋‹จ ํ•ด - 2๋ฐ”์ดํŠธ ๊ฒฝ๊ณ„์— ์ •๋ ฌ๋œ 4๋ฐ”์ดํŠธ smallint ๋‹ค์Œ ํ•„๋“œ ์•ž๊ณผ ๋งˆ์ง€๋ง‰ ํ•„๋“œ์ธ ๊ฒฝ์šฐ ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฉฐ ์ •๋ ฌํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค.

์ด๋ก ์ ์œผ๋กœ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ด๋ฉฐ ์›ํ•˜๋Š” ๋Œ€๋กœ ํ•„๋“œ๋ฅผ ๋‹ค์‹œ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ์ผ ์„น์…˜์ด 10-15GB๋ฅผ ์ฐจ์ง€ํ•˜๋Š” ํ…Œ์ด๋ธ” ์ค‘ ํ•˜๋‚˜์˜ ์˜ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ ๊ตฌ์กฐ:

CREATE TABLE public.plan_20190220
(
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  pack uuid NOT NULL,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  recno smallint NOT NULL,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  host uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  ts timestamp with time zone,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  exectime numeric(32,3),
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  duration numeric(32,3),
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufint bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufmem bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufdsk bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  apn uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  ptr uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  dt date,
  CONSTRAINT plan_20190220_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190220_dt_check CHECK (dt = '2019-02-20'::date)
)
INHERITS (public.plan)

์—ด ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„์˜ ์„น์…˜ - ์ •ํ™•ํžˆ ๊ฐ™์€ ํ•„๋“œ, ์ˆœ์„œ๋งŒ ๋‹ค๋ฅผ ๋ฟ:

CREATE TABLE public.plan_20190221
(
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  dt date NOT NULL,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  ts timestamp with time zone,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  pack uuid NOT NULL,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  recno smallint NOT NULL,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  host uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  apn uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  ptr uuid,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufint bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufmem bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  bufdsk bigint,
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  exectime numeric(32,3),
-- ะฃะฝะฐัะปะตะดะพะฒะฐะฝะฐ from table plan:  duration numeric(32,3),
  CONSTRAINT plan_20190221_pkey PRIMARY KEY (pack, recno),
  CONSTRAINT chck_ptr CHECK (ptr IS NOT NULL),
  CONSTRAINT plan_20190221_dt_check CHECK (dt = '2019-02-21'::date)
)
INHERITS (public.plan)

์„น์…˜์˜ ์ „์ฒด ๋ณผ๋ฅจ์€ "ํŒฉํŠธ"์˜ ์ˆ˜์— ๋”ฐ๋ผ ๊ฒฐ์ •๋˜๋ฉฐ ์™ธ๋ถ€ ํ”„๋กœ์„ธ์Šค์—๋งŒ ์˜์กดํ•˜๋ฏ€๋กœ ํž™์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜๋ˆ„์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(pg_relation_size) ๊ทธ ์•ˆ์— ์žˆ๋Š” ๋ ˆ์ฝ”๋“œ ์ˆ˜์— ๋”ฐ๋ผ - ์ฆ‰, ์šฐ๋ฆฌ๋Š” ์‹ค์ œ ์ €์žฅ๋œ ๊ธฐ๋ก์˜ ํ‰๊ท  ํฌ๊ธฐ:

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋งˆ์ด๋„ˆ์Šค 6% ๋ณผ๋ฅจ, ์—„์ฒญ๋‚œ!

๊ทธ๋Ÿฌ๋‚˜ ๋ฌผ๋ก  ๋ชจ๋“  ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ์žฅ๋ฐ‹๋น›์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์ธ๋ฑ์Šค์—์„œ๋Š” ํ•„๋“œ ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค., ๋”ฐ๋ผ์„œ "์ผ๋ฐ˜์ ์œผ๋กœ"(pg_total_relation_size) ...

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
...์•„์ง๋„ ์—ฌ๊ธฐ์— ์žˆ์–ด์š” 1.5% ์ ˆ์•ฝ์ฝ”๋“œ ํ•œ ์ค„๋„ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  ๋ง์ด์ฃ . ์˜ˆ, ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค!

PostgreSQL๋กœ ๋Œ€์šฉ๋Ÿ‰์„ ๊ตฌ๋งคํ•˜๋ฉด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ํ•„๋“œ ๋ฐฐ์—ด ์˜ต์…˜์ด ๊ฐ€์žฅ ์ตœ์ ์ด๋ผ๋Š” ์‚ฌ์‹ค์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ฏธํ•™์  ์ด์œ ๋กœ ์ผ๋ถ€ ํ•„๋“œ ๋ธ”๋ก์„ "์ฐข๊ณ " ์‹ถ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. (pack, recno), ์ด๋Š” ์ด ํ…Œ์ด๋ธ”์˜ PK์ž…๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ํ•„๋“œ์˜ "์ตœ์†Œ" ๋ฐฐ์—ด์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ•œ "๋ฌด์ฐจ๋ณ„์ ์ธ" ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๊ท€ํ•˜์˜ ๋ฐ์ดํ„ฐ์—์„œ ํ›จ์”ฌ ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณด์„ธ์š”!

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€