ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL

ืงืึทื ื˜ื™ื ื™ื•ื™ื ื’ ื“ื™ ื˜ืขืžืข ืคื•ืŸ โ€‹โ€‹ืจืขืงืึธืจื“ื™ื ื’ ื’ืจื•ื™ืก ื“ืึทื˜ืŸ ืกื˜ืจื™ืžื– ืื•ื™ืคืฉื˜ื™ื™ืŸ ื“ื•ืจืš ืคืจื™ื™ึทืขืจื“ื™ืง ืึทืจื˜ื™ืงืœ ื•ื•ืขื’ืŸ ืฆืขื˜ื™ื™ืœื•ื ื’, ืื™ืŸ ื“ืขื ืžื™ืจ ื•ื•ืขืœืŸ ืงื•ืงืŸ ืื™ืŸ ื“ื™ ื•ื•ืขื’ืŸ ืื™ืŸ ื•ื•ืึธืก ืื™ืจ ืงืขื ืขืŸ ืจืขื“ื•ืฆื™ืจืŸ ื“ื™ "ื’ืฉืžื™ื•ืช" ื’ืจื™ื™ืก ืคื•ืŸ ื“ื™ ืกื˜ืึธืจื“ ืื™ืŸ PostgreSQL, ืื•ืŸ ื–ื™ื™ืขืจ ืคึผืจืึทืœ ืื•ื™ืฃ ืกืขืจื•ื•ืขืจ ืคืึธืจืฉื˜ืขืœื•ื ื’.

ืžื™ืจ ื•ื•ืขืœืŸ ืจืขื“ืŸ ื•ื•ืขื’ืŸ TOAST ืกืขื˜ื˜ื™ื ื’ืก ืื•ืŸ ื“ืึทื˜ืŸ ืึทืœื™ื™ื ืžืึทื ื˜. "ืื™ืŸ ื“ื•ืจื›ืฉื ื™ื˜ืœืขืš," ื“ื™ ืžืขื˜ื”ืึธื“ืก ื•ื•ืขื˜ ื ื™ืฉื˜ ืฉืคึผืึธืจืŸ ืฆื• ืคื™ืœืข ืจืขืกื•ืจืกืŸ, ืึธื‘ืขืจ ืึธืŸ ืžืึธื“ื™ืคื™ืฆื™ืจืŸ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืงืึธื“.

ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL
ืึธื‘ืขืจ, ืื•ื ื“ื–ืขืจ ื“ืขืจืคืึทืจื•ื ื’ ืื™ื– ื’ืขื•ื•ืขืŸ ื–ื™ื™ืขืจ ืคึผืจืึธื“ื•ืงื˜ื™ื•ื• ืื™ืŸ ื“ืขื ืึทื›ื˜ื•ื ื’, ื•ื•ื™ื™ึทืœ ื“ื™ ืกื˜ืึธืจื™ื“ื–ืฉ ืคื•ืŸ ื›ึผืžืขื˜ ืงื™ื™ืŸ ืžืึธื ื™ื˜ืึธืจื™ื ื’ ืœื•ื™ื˜ ื–ื™ื™ึทืŸ ื ืึทื˜ื•ืจ ืื™ื– ืžืขืจืกื˜ื ืก ืฆื•ื’ืขื‘ืŸ-ื‘ืœื•ื™ื– ืื™ืŸ ื˜ืขืจืžื™ื ืขืŸ ืคื•ืŸ ืจืขืงืึธืจื“ืขื“ ื“ืึทื˜ืŸ. ืื•ืŸ ืื•ื™ื‘ ืื™ืจ ื–ืขื ื˜ ื•ื•ืึทื ื“ืขืจื™ื ื’ ื•ื•ื™ ืื™ืจ ืงืขื ืขืŸ ืœืขืจื ืขืŸ ื“ื™ ื“ืึทื˜ืึทื‘ื™ื™ืก ืฆื• ืฉืจื™ื™ึทื‘ืŸ ืฆื• ื“ื™ืกืง ืึทื ืฉื˜ืึธื˜ 200 ืžื‘ / s ื”ืึทืœื‘ ื•ื•ื™ ืคื™ืœ - ื‘ื™ื˜ืข ืื•ื ื˜ืขืจ ืงืึทืฅ.

ืงืœื™ื™ืŸ ืกื™ืงืจื™ืฅ ืคื•ืŸ ื’ืจื•ื™ืก ื“ืึทื˜ืŸ

ื“ื•ืจืš ืึทืจื‘ืขื˜ ืคึผืจืึธืคื™ืœ ืื•ื ื“ื–ืขืจ ื“ื™ื ืกื˜, ื–ื™ื™ ืคืœื™ืขืŸ ืงืขืกื™ื™ื“ืขืจ ืฆื• ืื™ื ืคื•ืŸ ื“ื™ ืœืขืจ ื˜ืขืงืกื˜ ืคึผืึทืงืึทื“ื–ืฉืึทื–.

ืื•ืŸ ื–ื™ื ื˜ VLSI ืงืึธืžืคึผืœืขืงืกื•ื•ืขืžืขื ืก ื“ืึทื˜ืึทื‘ื™ื™ืก ืžื™ืจ ืžืึธื ื™ื˜ืึธืจ ืื™ื– ืึท ืžืึทืœื˜ื™-ืงืึธืžืคึผืึธื ืขื ื˜ ืคึผืจืึธื“ื•ืงื˜ ืžื™ื˜ ืงืึธืžืคึผืœืขืงืก ื“ืึทื˜ืŸ ืกื˜ืจืึทืงื˜ืฉืขืจื–, ื“ืขืžืึธืœื˜ ืงื•ื•ื™ืจื™ื– ืคึฟืึทืจ ืžืึทืงืกื™ืžื•ื ืคืึธืจืฉื˜ืขืœื•ื ื’ ืงืขืจ ืื•ื™ืก ื’ืึทื ืฅ ื•ื•ื™ ื“ืึธืก "ืžืึทืœื˜ื™-ื‘ืึทื ื“" ืžื™ื˜ ืงืึธืžืคึผืœืขืงืก ืึทืœื’ืขืจื™ื“ืึทืžื™ืง ืœืึธื’ื™ืง. ืึทื–ื•ื™ ื“ืขืจ ื‘ืึทื ื“ ืคื•ืŸ ื™ืขื“ืขืจ ื™ื—ื™ื“ ื‘ื™ื™ึทืฉืคึผื™ืœ ืคื•ืŸ ืึท ื‘ืงืฉื” ืึธื“ืขืจ ื“ื™ ืจื™ื–ืึทืœื˜ื™ื ื’ ื“ื•ืจื›ืคื™ืจื•ื ื’ ืคึผืœืึทืŸ ืื™ืŸ ื“ื™ ืงืœืึธืฅ ื•ื•ืึธืก ืงื•ืžื˜ ืฆื• ืื•ื ื“ื– ื˜ื•ืจื ืก ืื•ื™ืก ืฆื• ื–ื™ื™ืŸ "ืื™ืŸ ื“ื•ืจื›ืฉื ื™ื˜ืœืขืš" ื’ืึทื ืฅ ื’ืจื•ื™ืก.

ื–ืืœ ืก ืงื•ืง ืื™ืŸ ื“ื™ ืกื˜ืจื•ืงื˜ื•ืจ ืคื•ืŸ ืื™ื™ื ืขืจ ืคื•ืŸ ื“ื™ ื˜ื™ืฉืŸ ืื™ืŸ ื•ื•ืึธืก ืžื™ืจ ืฉืจื™ื™ึทื‘ืŸ "ืจื•ื™" ื“ืึทื˜ืŸ - ื“ืึธืก ืื™ื–, ื“ืึธ ืื™ื– ื“ืขืจ ืึธืจื™ื’ื™ื ืขืœ ื˜ืขืงืกื˜ ืคื•ืŸ ื“ื™ ืงืœืึธืฅ ืคึผืึธื–ื™ืฆื™ืข:

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

ื ื˜ื™ืคึผื™ืฉ ืฆื™ื™ื›ืŸ (ืฉื•ื™ืŸ ืกืขืงืฉืึทื ื–, ืคื•ืŸ ืงื•ืจืก, ืึทื–ื•ื™ ื“ืึธืก ืื™ื– ืึท ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืžื•ืกื˜ืขืจ), ื•ื•ื• ื“ื™ ืžืขืจืกื˜ ื•ื•ื™ื›ื˜ื™ืง ื–ืึทืš ืื™ื– ื“ื™ ื˜ืขืงืกื˜. ืžืืœ ื’ืึทื ืฅ ื•ื•ืึทืœื•ืžืึทื ืึทืก.

ืฆื•ืจื™ืงืจื•ืคืŸ ืึทื– ื“ื™ "ื’ืฉืžื™ื•ืช" ื’ืจื™ื™ืก ืคื•ืŸ ืื™ื™ืŸ ืจืขืงืึธืจื“ ืื™ืŸ ืึท ืคึผื’ ืงืขืŸ ื ื™ืฉื˜ ืคืึทืจื ืขืžืขืŸ ืžืขืจ ื•ื•ื™ ืื™ื™ืŸ ื‘ืœืึทื˜ ืคื•ืŸ ื“ืึทื˜ืŸ, ืึธื‘ืขืจ ื“ื™ "ืœืึทื“ื–ืฉื™ืงืึทืœ" ื’ืจื™ื™ืก ืื™ื– ื’ืึธืจ ืึทื ื“ืขืจืฉ. ืฆื• ืฉืจื™ื™ึทื‘ืŸ ืึท ื•ื•ืึธืœื•ืžืขื˜ืจื™ืง ื•ื•ืขืจื˜ (ื•ื•ืึทืจื˜ืฉืึทืจ / ื˜ืขืงืกื˜ / ื‘ื™ื˜ืขืึท) ืฆื• ืึท ืคืขืœื“, ื ื•ืฆืŸ TOAST ื˜ืขื›ื ืึธืœืึธื’ื™ืข:

PostgreSQL ื ื™ืฆื˜ ืึท ืคืึทืจืคืขืกื˜ื™ืงื˜ ื‘ืœืึทื˜ ื’ืจื™ื™ืก (ื˜ื™ืคึผื™ืงืœื™ 8 ืงื‘), ืื•ืŸ ื˜ื•ื˜ ื ื™ืฉื˜ ืœืึธื–ืŸ ื˜ื•ืคึผืœืขืก ืฆื• ืฉืคึผืึทืŸ ืงื™ื™ืคืœ ื‘ืœืขื˜ืขืจ. ื“ืขืจื™ื‘ืขืจ, ืขืก ืื™ื– ืื•ืžืžืขื’ืœืขืš ืฆื• ื’ืœื™ื™ึทืš ืงืจืึธื ื–ื™ื™ืขืจ ื’ืจื•ื™ืก ืคืขืœื“ ื•ื•ืึทืœื•ืขืก. ืฆื• ื‘ืึทืงื•ืžืขืŸ ื“ืขื ื‘ืึทื’ืจืขื ืขืฆื•ื ื’, ื’ืจื•ื™ืก ืคืขืœื“ ื•ื•ืึทืœื•ืขืก ื–ืขื ืขืŸ ืงืึทืžืคึผืจืขืกื˜ ืื•ืŸ / ืึธื“ืขืจ ืฉืคึผืึทืœื˜ืŸ ืื•ื™ืฃ ืงื™ื™ืคืœ ื’ืฉืžื™ื•ืช ืฉื•ืจื•ืช. ื“ืขื ื›ืึทืคึผืึทื ื– ืึทื ื ืึธื•ื˜ื™ืกื˜ ื“ื•ืจืš ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืื•ืŸ ื”ืื˜ ืึท ืงืœื™ื™ืŸ ืคึผืจืึทืœ ืื•ื™ืฃ ืจื•ื‘ึฟ ืกืขืจื•ื•ืขืจ ืงืึธื“. ื“ืขืจ ืื•ืคึฟืŸ ืื™ื– ื‘ืืงืื ื˜ ื•ื•ื™ TOAST ...

ืื™ืŸ ืคืึทืงื˜, ืคึฟืึทืจ ื™ืขื“ืขืจ ื˜ื™ืฉ ืžื™ื˜ "ืคึผืึทื˜ืขื ื˜ืฉืึทืœื™ ื’ืจื•ื™ืก" ืคืขืœื“ืขืจ, ืื•ื™ื˜ืึธืžืึทื˜ื™ืฉ ืึท ืคึผืขืจื“ ื˜ื™ืฉ ืžื™ื˜ "ืกืœื™ื™ืกื™ื ื’" ืื™ื– ื‘ืืฉืืคืŸ ื™ืขื“ืขืจ "ื’ืจื•ื™ืก" ืจืขืงืึธืจื“ ืื™ืŸ 2KB ืกืขื’ืžืึทื ืฅ:

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

ืึทื– ืื™ื–, ืื•ื™ื‘ ืžื™ืจ ื”ืึธื‘ืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ืึท ืฉื˜ืจื™ืงืœ ืžื™ื˜ ืึท "ื’ืจื•ื™ืก" ื•ื•ืขืจื˜ data, ื“ืขืžืึธืœื˜ ื“ืขืจ ืขืžืขืก ืจืขืงืึธืจื“ื™ื ื’ ื•ื•ืขื˜ ืคึผืึทืกื™ืจืŸ ื ื™ื˜ ื‘ืœื•ื™ื– ืฆื• ื“ื™ ื”ื•ื™ืคึผื˜ ื˜ื™ืฉ ืื•ืŸ ื–ื™ื™ึทืŸ ืคึผืง, ืึธื‘ืขืจ ืื•ื™ืš ืฆื• 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 ืžืืœ ื•ื•ื™ื™ื ื™ืงืขืจ ืึธืคื˜, ื•ื•ืึธืก ืึทื ืœืึธื•ื“ื™ื“ ื ื™ื˜ ื‘ืœื•ื™ื– ื“ื™ ื“ื™ืกืง, ืึธื‘ืขืจ ืื•ื™ืš ื“ื™ ืงืคึผื•:

ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL
ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL
ืื™ืš ื•ื•ืขืœ ื‘ืืžืขืจืงืŸ ืื– ืžื™ืจ ื–ืขื ืขืŸ ืื•ื™ืš ื’ืขื•ื•ืืจืŸ ืงืœืขื ืขืจ ืื™ืŸ "ืœื™ื™ืขื ืขืŸ" ื“ืขื ื“ื™ืกืง, ื ื™ืฉื˜ ื‘ืœื•ื™ื– "ืฉืจื™ื™ื‘ืŸ" - ื•ื•ื™ื™ืœ ื•ื•ืขืŸ ืžืขืŸ ืœื™ื™ื’ื˜ ืืจื™ื™ืŸ ื ืจืขืงืืจื“ ืื™ืŸ ื ื˜ื™ืฉ, ื“ืืจืคืŸ ืžื™ืจ ืื•ื™ืš "ืœื™ื™ืขื ืขืŸ" ื˜ื™ื™ืœ ืคื•ื ืขื ื‘ื•ื™ื ืคื•ืŸ ื™ืขื“ืŸ ืื™ื ื“ืขืงืก ื›ื“ื™ ืฆื• ื‘ืืฉื˜ื™ืžืขืŸ ื–ื™ื™ืŸ ืฆื•ืงื•ื ืคึฟื˜ ืฉื˜ืขืœืข ืื™ืŸ ื–ื™ื™.

ื•ื•ืขืจ ืงืขื ืขืŸ ืœืขื‘ืŸ ื’ืขื–ื•ื ื˜ ืื•ื™ืฃ PostgreSQL 11

ื ืึธืš ืึทืคึผื“ื™ื™ื˜ื™ื ื’ ืฆื• PG11, ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืคืึธืจื–ืขืฆืŸ "ื˜ื•ื ื™ื ื’" TOAST ืื•ืŸ ื‘ืืžืขืจืงื˜ ืึทื– ืกื˜ืึทืจื˜ื™ื ื’ ืคื•ืŸ ื“ืขื ื•ื•ืขืจืกื™ืข ื“ื™ ืคึผืึทืจืึทืžืขื˜ืขืจ toast_tuple_target:

ื“ื™ TOAST ืคึผืจืึทืกืขืกื™ื ื’ ืงืึธื“ ืคื™ืจื– ื‘ืœื•ื™ื– ื•ื•ืขืŸ ื“ื™ ืจื•ื“ืขืจืŸ ื•ื•ืขืจื˜ ืฆื• ื–ื™ื™ืŸ ืกื˜ืึธืจื“ ืื™ืŸ ื“ื™ ื˜ื™ืฉ ืื™ื– ื’ืจืขืกืขืจ ื•ื•ื™ TOAST_TUPLE_THRESHOLD ื‘ื™ื˜ืขืก (ื™ื•ื–ืฉืึทื•ื•ืึทืœื™ 2 ืงื‘). ื“ื™ TOAST ืงืึธื“ ื•ื•ืขื˜ ืงืึธืžืคึผืจืขืก ืื•ืŸ / ืึธื“ืขืจ ืžืึทืš ืคืขืœื“ ื•ื•ืึทืœื•ืขืก ืื•ื™ืก ืคื•ืŸ ื“ื™ ื˜ื™ืฉ ื‘ื™ื– ื“ื™ ืจื•ื“ืขืจืŸ ื•ื•ืขืจื˜ ื•ื•ืขืจื˜ ื•ื•ื™ื™ื ื™ืงืขืจ ื•ื•ื™ TOAST_TUPLE_TARGET ื‘ื™ื˜ืขืก (ื‘ื™ื™ึทื˜ืœืขืš ื•ื•ืขืจื˜, ืื•ื™ืš ื™ื•ื–ืฉืึทื•ื•ืึทืœื™ 2 ืงื‘) ืึธื“ืขืจ ื“ื™ ื’ืจื™ื™ืก ืงืขื ืขืŸ ื ื™ื˜ ื–ื™ื™ืŸ ืจื™ื“ื•ืกื˜.

ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืึทื– ื“ื™ ื“ืึทื˜ืŸ ื•ื•ืึธืก ืžื™ืจ ื™ื•ื–ืฉืึทื•ื•ืึทืœื™ ื”ืึธื‘ืŸ ืื™ื– ืึธื“ืขืจ "ื–ื™ื™ืขืจ ืงื•ืจืฅ" ืึธื“ืขืจ "ื–ื™ื™ืขืจ ืœืึทื ื’", ืึทื–ื•ื™ ืžื™ืจ ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื‘ืึทื’ืจืขื ืขืฆืŸ ื–ื™ืš ืฆื• ื“ื™ ืžื™ื ื™ืžื•ื ืžืขื’ืœืขืš ื•ื•ืขืจื˜:

ALTER TABLE rawplan_orig SET (toast_tuple_target = 128);

ืœืึธืžื™ืจ ื–ืขืŸ ื•ื•ื™ ื“ื™ ื ื™ื™ึทืข ืกืขื˜ื˜ื™ื ื’ืก ืึทืคืขืงื˜ืึทื“ ื“ื™ืกืง ืœืึธื•ื“ื™ื ื’ ื ืึธืš ืจื™ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ:

ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL
ื ื™ืฉื˜ ืฉืœืขื›ื˜! ื“ื•ืจื›ืฉื ื™ื˜ืœืขืš ื“ื™ ืจื™ื™ ืฆื• ื“ื™ ื“ื™ืกืง ืื™ื– ื“ื™ืงืจื™ืกื˜ ื‘ืขืขืจืขืš 1.5 ืžืืœ, ืื•ืŸ ื“ืขืจ ื“ื™ืกืง "ืคืึทืจื ื•ืžืขืŸ" ืื™ื– 20 ืคึผืจืึธืฆืขื ื˜! ืื‘ืขืจ ืืคึฟืฉืจ ื“ืึธืก ืขืคืขืก ืึทืคืขืงื˜ืึทื“ ื“ื™ ืงืคึผื•?

ืฉืคึผืึธืจืŸ ืึท ืคึผืขื ื™ ืคึฟืึทืจ ื’ืจื•ื™ืก ื•ื•ืึทืœื™ื•ืžื– ืื™ืŸ PostgreSQL
ืขืก ืื™ื– ื›ืื˜ืฉ ื ื™ืฉื˜ ืขืจื’ืขืจ ื’ืขื•ื•ืืจืŸ. ื›ืึธื˜ืฉ, ืขืก ืื™ื– ืฉื•ื•ืขืจ ืฆื• ืจื™ื›ื˜ืขืจ ืื•ื™ื‘ ืืคื™ืœื• ืึทื–ืึท ื•ื•ืึทืœื™ื•ืžื– ื ืึธืš ืงืขื ืขืŸ ื ื™ืฉื˜ ื›ืึทืคึผืŸ ื“ื™ ื“ื•ืจื›ืฉื ื™ื˜ืœืขืš ืงืคึผื• ืžืึทืกืข ื”ืขื›ืขืจ 5%.

ื“ื•ืจืš ื˜ื•ื™ืฉืŸ ื“ื™ ืขืจื˜ืขืจ ืคื•ืŸ ื“ื™ ื˜ืขืจืžื™ื ืขืŸ, ื“ื™ ืกืึทื›ืึทืงืœ ... ืขื ื“ืขืจื•ื ื’ืขืŸ!

ื•ื•ื™ ืื™ืจ ื•ื•ื™ืกืŸ, ืึท ืคึผืขื ื™ ืกืึทื•ื•ืขืก ืึท ืจื•ื‘ืœ, ืื•ืŸ ืžื™ื˜ ืื•ื ื“ื–ืขืจ ืกื˜ืึธืจื™ื“ื–ืฉ ื•ื•ืึทืœื™ื•ืžื– ืขืก ืื™ื– ื•ื•ืขื’ืŸ 10 ื˜ื‘ / ื—ื•ื“ืฉ ืืคื™ืœื• ืึท ื‘ื™ืกืœ ืึทืคึผื˜ืึทืžืึทื–ื™ื™ืฉืึทืŸ ืงืขื ืขืŸ ื’ืขื‘ืŸ ืึท ื’ื•ื˜ ื ื•ืฅ. ื“ืขืจื™ื‘ืขืจ, ืžื™ืจ ื‘ืึทืฆืึธืœื˜ ื•ืคืžืขืจืงื–ืึทืžืงื™ื™ึทื˜ ืฆื• ื“ื™ ื’ืฉืžื™ื•ืช ืกื˜ืจื•ืงื˜ื•ืจ ืคื•ืŸ ืื•ื ื“ื–ืขืจ ื“ืึทื˜ืŸ - ื•ื•ื™ ืคึผื•ื ืงื˜ "ืกื˜ืึทืงื˜" ืคืขืœื“ืขืจ ืื™ืŸ ื“ื™ ืจืขืงืึธืจื“ ื™ืขื“ืขืจ ืคื•ืŸ ื“ื™ ื˜ื™ืฉืŸ.

ื•ื•ื™ื™ึทืœ ื•ื•ื™ื™ึทืœ ืคื•ืŸ ื“ืึทื˜ืŸ ืึทืœื™ื™ื ืžืึทื ื˜ ื“ืึธืก ืื™ื– ื’ืœื™ื™ึทืš ืคืึธืจื•ื™ืก ืึทืคืขืงืฅ ื“ื™ ืจื™ื–ืึทืœื˜ื™ื ื’ ื‘ืึทื ื“:

ืคื™ืœืข ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจื– ืฆื•ืฉื˜ืขืœืŸ ื“ืึทื˜ืŸ ืึทืœื™ื™ื ืžืึทื ื˜ ืื•ื™ืฃ ืžืึทืฉื™ืŸ ื•ื•ืึธืจื˜ ื‘ืึทื•ื ื“ืจื™ื–. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ืื•ื™ืฃ ืึท 32-ื‘ื™ืกืœ ืงืก86 ืกื™ืกื˜ืขื, ื™ื ื˜ืึทื“ื–ืฉืขืจื– (ื™ื ื˜ืึทื“ื–ืฉืขืจ ื˜ื™ืคึผ, 4 ื‘ื™ื˜ืขืก) ื•ื•ืขื˜ ื–ื™ื™ืŸ ืึทืœื™ื™ื ื“ ืื•ื™ืฃ ืึท 4-ื‘ื™ื˜ืข ื•ื•ืึธืจื˜ ื’ืจืขื ืขืฅ, ื•ื•ื™ ื•ื•ืขื˜ ื˜ืึธืคึผืœ ืคึผื™ื ื˜ืœืขื›ืงื™ื™ึทื˜ ืคืœืึธื•ื˜ื™ื ื’ ืคื•ื ื˜ ื ื•ืžืขืจืŸ (ื˜ืึธืคึผืœ ืคึผื™ื ื˜ืœืขื›ืงื™ื™ึทื˜ ืคืœืึธื•ื˜ื™ื ื’ ืคื•ื ื˜, 8 ื‘ื™ื˜ืขืก). ืื•ืŸ ืื•ื™ืฃ ืึท 64-ื‘ื™ืกืœ ืกื™ืกื˜ืขื, ื˜ืึธืคึผืœ ื•ื•ืึทืœื•ืขืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ืึทืœื™ื™ื ื“ ืฆื• 8-ื‘ื™ื˜ืข ื•ื•ืึธืจื˜ ื‘ืึทื•ื ื“ืจื™ื–. ื“ืึธืก ืื™ื– ืืŸ ืื ื“ืขืจ ืกื™ื‘ื” ืคึฟืึทืจ ื™ื ืงืึทืžืคึผืึทื˜ืึทื‘ื™ืœืึทื˜ื™.

ืจืขื›ื˜ ืฆื• ืึทืœื™ื™ื ืžืึทื ื˜, ื“ื™ ื’ืจื™ื™ืก ืคื•ืŸ ืึท ื˜ื™ืฉ ืจื•ื“ืขืจืŸ ื“ืขืคึผืขื ื“ืก ืื•ื™ืฃ ื“ื™ ืกื“ืจ ืคื•ืŸ ื“ื™ ืคืขืœื“ืขืจ. ื™ื•ื–ืฉืึทื•ื•ืึทืœื™ ื“ืขื ื•ื•ื™ืจืงื•ื ื’ ืื™ื– ื ื™ืฉื˜ ื–ื™ื™ืขืจ ื‘ืืžืขืจืงื˜, ืึธื‘ืขืจ ืื™ืŸ ืขื˜ืœืขื›ืข ืงืึทืกืขืก ืขืก ืงืขืŸ ืคื™ืจืŸ ืฆื• ืึท ื‘ืึทื˜ื™ื™ื˜ื™ืง ืคืึทืจื’ืจืขืกืขืจืŸ ืื™ืŸ ื’ืจื™ื™ืก. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ืื•ื™ื‘ ืื™ืจ ืžื™ืฉืŸ ื˜ืฉืึทืจ (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-ื‘ื™ื˜ืข ื’ืจืขื ืขืฅ ืื™ื™ื“ืขืจ ื“ื™ ื•ื•ื™ื™ึทื˜ืขืจ ืคืขืœื“, ืื•ืŸ ื•ื•ืขืŸ ืขืก ืื™ื– ื“ื™ ืœืขืฆื˜ืข, ืขืก ืื™ื– ื’ืึธืจื ื™ืฉื˜ ืื•ืŸ ื ื™ื˜ ื“ืึทืจืคึฟืŸ ืฆื• ื™ื™ึทื ืจื™ื™ืขืŸ.

ืื™ืŸ ื˜ืขืึธืจื™ืข, ืึทืœืฅ ืื™ื– ื’ื•ื˜ ืื•ืŸ ืื™ืจ ืงืขื ืขืŸ ืจื™ืขืจื™ื™ื ื“ื–ืฉ ื“ื™ ืคืขืœื“ืขืจ ื•ื•ื™ ืื™ืจ ื•ื•ื™ืœื˜. ืœืึธืžื™ืจ ืงืึธื ื˜ืจืึธืœื™ืจืŸ ืขืก ืื•ื™ืฃ ืคืึทืงื˜ื™ืฉ ื“ืึทื˜ืŸ ืžื™ื˜ ื“ืขื ื‘ื™ื™ึทืฉืคึผื™ืœ ืคื•ืŸ ืื™ื™ื ืขืจ ืคื•ืŸ ื“ื™ ื˜ื™ืฉืŸ, ื“ื™ ื˜ืขื’ืœืขืš ืึธืคึผื˜ื™ื™ืœื•ื ื’ ืคื•ืŸ ื•ื•ืึธืก ืึทืงื™ืึทืคึผื™ื™ื– 10-15 ื’ื‘.

ืขืจืฉื˜ ืกื˜ืจื•ืงื˜ื•ืจ:

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), ื•ื•ืึธืก ืื™ื– ื“ื™ ืคึผืง ืคึฟืึทืจ ื“ืขื ื˜ื™ืฉ.

ืื™ืŸ ืึทืœื’ืขืžื™ื™ืŸ, ื‘ืึทืฉื˜ื™ืžืขืŸ ื“ื™ "ืžื™ื ื™ืžื•ื" ืึธืจื“ืขื ื•ื ื’ ืคื•ืŸ ืคืขืœื“ืขืจ ืื™ื– ืึท ื’ืึทื ืฅ ืคึผืฉื•ื˜ "ื‘ืจื•ื˜ ืงืจืึทืคื˜" ืึทืจื‘ืขื˜. ื“ืขืจื™ื‘ืขืจ, ืื™ืจ ืงืขื ืขืŸ ื‘ืึทืงื•ืžืขืŸ ืืคื™ืœื• ื‘ืขืกืขืจ ืจืขื–ื•ืœื˜ืึทื˜ืŸ ืคื•ืŸ ื“ื™ื™ืŸ ื“ืึทื˜ืŸ ื•ื•ื™ ืื•ื ื“ื–ืขืจ - ืคึผืจื•ึผื•ื•ื˜ ืขืก!

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’