PostgreSQL์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ

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

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

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

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

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

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

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

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์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ
PostgreSQL์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ
๋˜ํ•œ, ๋””์Šคํฌ๋ฅผ "์“ฐ๊ธฐ"๋งŒ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ "์ฝ๊ธฐ"๋„ ๋œ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์–ด๋–ค ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ๋•Œ, ๊ฐ ์ธ๋ฑ์Šค์˜ ํŠธ๋ฆฌ ์ผ๋ถ€๋ฅผ "์ฝ์–ด์„œ" ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ๋ฏธ๋ž˜ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

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ํŽ˜๋‹ˆ ์ ˆ์•ฝ
๋‚˜์˜์ง€ ์•Š๋„ค์š”! ํ‰๊ท  ๋””์Šคํฌ ๋Œ€๊ธฐ์—ด์ด ์ค„์—ˆ์Šต๋‹ˆ๋‹ค ์•ฝ 1.5๋ฐฐ์ด๊ณ  ๋””์Šคํฌ "์ ์œ ์œจ"์€ 20%์ž…๋‹ˆ๋‹ค! ํ•˜์ง€๋งŒ ์–ด์ฉŒ๋ฉด CPU์— ์˜ํ–ฅ์„ ๋ฏธ์ณค์„ ์ˆ˜๋„ ์žˆ์„๊นŒ?

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

ํ•ญ์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋ฉด ํ•ฉ๊ณ„๊ฐ€ ๋ฐ”๋€Œ์ฃ !

์•„์‹œ๋‹ค์‹œํ”ผ, ์ ˆ์•ฝํ•œ 1ํŽ˜๋‹ˆ๋Š” ๋ฒŒ์–ด๋“ค์ธ 1ํŽ˜๋‹ˆ์™€ ๊ฐ™์œผ๋ฉฐ, ์šฐ๋ฆฌ์˜ ์ €์žฅ ์šฉ๋Ÿ‰์—๋Š” ์ฃผ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 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๋ฐ”์ดํŠธ smallint๋Š” 4๋ฐ”์ดํŠธ ๊ฒฝ๊ณ„์— ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ํ•„๋“œ ์ „, ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ํ•„๋“œ์ผ ๋•Œ๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฏ€๋กœ ์ •๋ ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ด๋ก ์ƒ์œผ๋กœ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๊ดœ์ฐฎ์œผ๋ฉฐ ์›ํ•˜๋Š” ๋Œ€๋กœ ํ•„๋“œ๋ฅผ ์žฌ๋ฐฐ์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ ํ…Œ์ด๋ธ” ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ์—์„œ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ํ…Œ์ด๋ธ”์˜ ์ผ์ผ ์„น์…˜์€ 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์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ
๋งˆ์ด๋„ˆ์Šค 6% ๋ณผ๋ฅจ, ์—„์ฒญ๋‚œ!

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

PostgreSQL์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ
โ€ฆ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ๋„ ๊ฒฐ๊ตญ 1.5% ์ ˆ์•ฝ์ฝ”๋“œ ํ•œ ์ค„๋„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„. ๋ฌผ๋ก ์ด์ฃ !

PostgreSQL์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ณผ๋ฅจ์— 1ํŽ˜๋‹ˆ ์ ˆ์•ฝ

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

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

์ถœ์ฒ˜ : habr.com