เจœเจฆเฉ‹เจ‚ เจตเฉˆเจ•เจฟเจŠเจฎ เจ…เจธเจซเจฒ เจนเฉ‹ เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจ…เจธเฉ€เจ‚ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจนเฉฑเจฅเฉ€เจ‚ เจธเจพเจซเจผ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚

เจตเฉˆเจ•เฉ‚เจฎ PostgreSQL เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจŸเฉ‡เจฌเจฒ เจคเฉ‹เจ‚ "เจธเจพเจซเจผ" เจ•เจฐ เจธเจ•เจฆเจพ เจนเฉˆ เจธเจฟเจฐเจซเจผ เจ•เฉ€ เจ•เฉ‹เจˆ เจจเจนเฉ€เจ‚ เจฆเฉ‡เจ– เจธเจ•เจฆเจพ - เจญเจพเจต, เจ‡เฉฑเจฅเฉ‡ เจ‡เฉฑเจ• เจตเฉ€ เจ•เจฟเจฐเจฟเจ†เจธเจผเฉ€เจฒ เจฌเฉ‡เจจเจคเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ เจœเฉ‹ เจ‡เจนเจจเจพเจ‚ เจฐเจฟเจ•เจพเจฐเจกเจพเจ‚ เจจเฉ‚เฉฐ เจฌเจฆเจฒเจฃ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจธเจผเฉเจฐเฉ‚ เจนเฉ‹เจˆ เจธเฉ€เฅค

เจชเจฐ เจ•เฉ€ เจœเฉ‡ เจ…เจœเจฟเจนเฉ€ เจ•เฉ‹เจเจพ เจ•เจฟเจธเจฎ (เจ‡เฉฑเจ• OLTP เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ 'เจคเฉ‡ เจฒเฉฐเจฌเฉ‡ เจธเจฎเฉ‡เจ‚ เจฒเจˆ OLAP เจฒเฉ‹เจก) เจ…เจœเฉ‡ เจตเฉ€ เจฎเฉŒเจœเฉ‚เจฆ เจนเฉˆ? เจ•เจฟเจตเฉ‡เจ‚ เจธเจฐเจ—เจฐเจฎเฉ€ เจจเจพเจฒ เจฌเจฆเจฒเจฃ เจตเจพเจฒเฉ€ เจธเจพเจฐเจฃเฉ€ เจจเฉ‚เฉฐ เจธเจพเจซเจผ เจ•เจฐเฉ‹ เจฒเฉฐเจฌเฉ‡ เจธเจตเจพเจฒเจพเจ‚ เจจเจพเจฒ เจ˜เจฟเจฐเจฟเจ† เจนเฉ‹เจ‡เจ† เจนเฉˆ เจ…เจคเฉ‡ เจฐเฉ‡เจ• 'เจคเฉ‡ เจ•เจฆเจฎ เจจเจนเฉ€เจ‚ เจฐเฉฑเจ–เจฆเจพ?

เจœเจฆเฉ‹เจ‚ เจตเฉˆเจ•เจฟเจŠเจฎ เจ…เจธเจซเจฒ เจนเฉ‹ เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจ…เจธเฉ€เจ‚ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจนเฉฑเจฅเฉ€เจ‚ เจธเจพเจซเจผ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚

เจฐเฉ‡เจ• เจจเฉ‚เฉฐ เจ–เฉ‹เจฒเฉเจนเจฃเจพ

เจชเจนเจฟเจฒเจพเจ‚, เจ†เจ“ เจ‡เจน เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเฉ€เจ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ•เจฟเจนเฉœเฉ€ เจธเจฎเฉฑเจธเจฟเจ† เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ เจ‡เจน เจ•เจฟเจตเฉ‡เจ‚ เจชเฉˆเจฆเจพ เจนเฉ‹ เจธเจ•เจฆเฉ€ เจนเฉˆเฅค

เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‡เจน เจธเจฅเจฟเจคเฉ€ เจตเจพเจชเจฐเจฆเฉ€ เจนเฉˆ เจ‡เฉฑเจ• เจฎเฉเจ•เจพเจฌเจฒเจคเจจ เจ›เฉ‹เจŸเฉ€ เจฎเฉ‡เจœเจผ 'เจคเฉ‡, เจชเจฐ เจœเจฟเจธ เจตเจฟเฉฑเจš เจ‡เจน เจตเจพเจชเจฐเจฆเจพ เจนเฉˆ เจฌเจนเฉเจค เจธเจพเจฐเฉ€เจ†เจ‚ เจคเจฌเจฆเฉ€เจฒเฉ€เจ†เจ‚. เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‡เจน เจœเจพเจ‚ เจตเฉฑเจ–เจฐเจพ เจฎเฉ€เจŸเจฐ/เจเจ—เจฐเฉ€เจ—เฉ‡เจŸ/เจฐเฉ‡เจŸเจฟเฉฐเจ—, เจœเจฟเจธ 'เจคเฉ‡ เจ…เฉฑเจชเจกเฉ‡เจŸ เจ…เจ•เจธเจฐ เจšเจฒเจพเจ‡เจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจœเจพเจ‚ เจฌเจซเจฐ-เจ•เจคเจพเจฐ เจ‡เจตเฉˆเจ‚เจŸเจธ เจฆเฉ‡ เจ•เฉเจ เจฒเจ—เจพเจคเจพเจฐ เจšเฉฑเจฒ เจฐเจนเฉ‡ เจธเจŸเฉเจฐเฉ€เจฎ 'เจคเฉ‡ เจ•เจพเจฐเจตเจพเจˆ เจ•เจฐเจจ เจฒเจˆ, เจœเจฟเจจเฉเจนเจพเจ‚ เจฆเฉ‡ เจฐเจฟเจ•เจพเจฐเจก เจฒเจ—เจพเจคเจพเจฐ INSERT/DELETE เจ•เฉ€เจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจเฅค

เจ†เจ‰ เจฐเฉ‡เจŸเจฟเฉฐเจ—เจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจตเจฟเจ•เจฒเจช เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเฉ€เจ:

CREATE TABLE tbl(k text PRIMARY KEY, v integer);
CREATE INDEX ON tbl(v DESC); -- ะฟะพ ัั‚ะพะผัƒ ะธะฝะดะตะบััƒ ะฑัƒะดะตะผ ัั‚ั€ะพะธั‚ัŒ ั€ะตะนั‚ะธะฝะณ

INSERT INTO
  tbl
SELECT
  chr(ascii('a'::text) + i) k
, 0 v
FROM
  generate_series(0, 25) i;

เจ…เจคเฉ‡ เจธเจฎเจพเจจเจพเจ‚เจคเจฐ เจตเจฟเฉฑเจš, เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจ•เฉเจจเฉˆเจ•เจธเจผเจจ เจตเจฟเฉฑเจš, เจ‡เฉฑเจ• เจฒเฉฐเจฎเฉ€, เจฒเฉฐเจฎเฉ€ เจฌเฉ‡เจจเจคเฉ€ เจธเจผเฉเจฐเฉ‚ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ, เจ•เฉเจ เจ—เฉเฉฐเจเจฒเจฆเจพเจฐ เจ…เฉฐเจ•เฉœเฉ‡ เจ‡เจ•เฉฑเจ เฉ‡ เจ•เจฐเจฆเฉ‡ เจนเจจ, เจชเจฐ เจธเจพเจกเฉ‡ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจชเฉเจฐเจญเจพเจตเจฟเจค เจจเจนเฉ€เจ‚ เจ•เจฐ เจฐเจฟเจนเจพ:

SELECT pg_sleep(10000);

เจนเฉเจฃ เจ…เจธเฉ€เจ‚ เจ•เจพเจŠเจ‚เจŸเจฐเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ‡เฉฑเจ• เจฆเฉ‡ เจฎเฉเฉฑเจฒ เจจเฉ‚เฉฐ เจ•เจˆ, เจ•เจˆ เจตเจพเจฐ เจ…เฉฑเจชเจกเฉ‡เจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจชเฉเจฐเจฏเฉ‹เจ— เจฆเฉ€ เจธเจผเฉเฉฑเจงเจคเจพ เจฒเจˆ, เจ†เจ“ เจ‡เจน เจ•เจฐเฉ€เจ dblink เจตเจฐเจค เจ•เฉ‡ เจตเฉฑเจ–เจฐเฉ‡ เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจตเจฟเฉฑเจšเจ‡เจน เจ…เจธเจฒเฉ€เจ…เจค เจตเจฟเฉฑเจš เจ•เจฟเจตเฉ‡เจ‚ เจนเฉ‹เจตเฉ‡เจ—เจพ:

DO $$
DECLARE
  i integer;
  tsb timestamp;
  tse timestamp;
  d double precision;
BEGIN
  PERFORM dblink_connect('dbname=' || current_database() || ' port=' || current_setting('port'));
  FOR i IN 1..10000 LOOP
    tsb = clock_timestamp();
    PERFORM dblink($e$UPDATE tbl SET v = v + 1 WHERE k = 'a';$e$);
    tse = clock_timestamp();
    IF i % 1000 = 0 THEN
      d = (extract('epoch' from tse) - extract('epoch' from tsb)) * 1000;
      RAISE NOTICE 'i = %, exectime = %', lpad(i::text, 5), lpad(d::text, 5);
    END IF;
  END LOOP;
  PERFORM dblink_disconnect();
END;
$$ LANGUAGE plpgsql;

NOTICE:  i =  1000, exectime = 0.524
NOTICE:  i =  2000, exectime = 0.739
NOTICE:  i =  3000, exectime = 1.188
NOTICE:  i =  4000, exectime = 2.508
NOTICE:  i =  5000, exectime = 1.791
NOTICE:  i =  6000, exectime = 2.658
NOTICE:  i =  7000, exectime = 2.318
NOTICE:  i =  8000, exectime = 2.572
NOTICE:  i =  9000, exectime = 2.929
NOTICE:  i = 10000, exectime = 3.808

เจ•เฉ€ เจนเฉ‹เจ‡เจ†? เจ‡เฉฑเจ• เจธเจฟเฉฐเจ—เจฒ เจฐเจฟเจ•เจพเจฐเจก เจฆเฉ‡ เจธเจงเจพเจฐเจจ เจ…เฉฑเจชเจกเฉ‡เจŸ เจฒเจˆ เจตเฉ€ เจ•เจฟเจ‰เจ‚ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจŸเจพเจˆเจฎ 7 เจ—เฉเจฃเจพ เจ˜เจŸเจพเจ‡เจ† เจ—เจฟเจ† - 0.524ms เจคเฉ‹เจ‚ 3.808ms เจคเฉฑเจ•? เจ…เจคเฉ‡ เจธเจพเจกเฉ€ เจฐเฉ‡เจŸเจฟเฉฐเจ— เจนเฉŒเจฒเฉ€-เจนเฉŒเจฒเฉ€ เจฌเจฃ เจฐเจนเฉ€ เจนเฉˆเฅค

เจ‡เจน เจธเจญ MVCC เจฆเจพ เจ•เจธเฉ‚เจฐ เจนเฉˆเฅค

เจ‡เจน เจธเจญ เจฆเฉ‡ เจฌเจพเจฐเฉ‡ เจนเฉˆ MVCC เจตเจฟเจงเฉ€, เจœเฉ‹ เจ•เจฟ เจ‡เฉฐเจฆเจฐเจพเจœเจผ เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจชเจฟเจ›เจฒเฉ‡ เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ เจจเฉ‚เฉฐ เจตเฉ‡เจ–เจฃ เจฒเจˆ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฆเจพ เจ•เจพเจฐเจจ เจฌเจฃเจฆเจพ เจนเฉˆเฅค เจ‡เจธ เจฒเจˆ เจ†เจ“ เจ†เจชเจฃเฉ‡ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ "เจฎเฉเจฐเจฟเจค" เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ เจคเฉ‹เจ‚ เจธเจพเจซเจผ เจ•เจฐเฉ€เจ:

VACUUM VERBOSE tbl;

INFO:  vacuuming "public.tbl"
INFO:  "tbl": found 0 removable, 10026 nonremovable row versions in 45 out of 45 pages
DETAIL:  10000 dead row versions cannot be removed yet, oldest xmin: 597439602

เจ“เจน, เจธเจพเจซเจผ เจ•เจฐเจจ เจฒเจˆ เจ•เฉเจ เจตเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ! เจธเจฎเจพเจจเจพเจ‚เจคเจฐ เจšเฉฑเจฒ เจฐเจนเฉ€ เจฌเฉ‡เจจเจคเฉ€ เจธเจพเจกเฉ‡ เจจเจพเจฒ เจฆเจ–เจฒ เจฆเฉ‡ เจฐเจนเฉ€ เจนเฉˆ - เจ†เจ–เจฐเจ•เจพเจฐ, เจ‰เจน เจ•เจฟเจธเฉ‡ เจฆเจฟเจจ เจ‡เจนเจจเจพเจ‚ เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ (เจœเฉ‡เจ•เจฐ?) เจตเฉฑเจฒ เจฎเฉเฉœเจจเจพ เจšเจพเจน เจธเจ•เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ‰เจน เจ‰เจธ เจฒเจˆ เจ‰เจชเจฒเจฌเจง เจนเฉ‹เจฃเฉ‡ เจšเจพเจนเฉ€เจฆเฉ‡ เจนเจจ. เจ…เจคเฉ‡ เจ‡เจธ เจฒเจˆ เจตเฉˆเจ•เจฟเจŠเจฎ เจซเฉเจฒ เจตเฉ€ เจธเจพเจกเฉ€ เจฎเจฆเจฆ เจจเจนเฉ€เจ‚ เจ•เจฐเฉ‡เจ—เจพเฅค

เจธเจพเจฐเจฃเฉ€ เจจเฉ‚เฉฐ "เจŸเฉเฉฑเจŸเจฃเจพ"

เจชเจฐ เจ…เจธเฉ€เจ‚ เจฏเจ•เฉ€เจจเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจœเจพเจฃเจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ‰เจธ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจจเฉ‚เฉฐ เจธเจพเจกเฉ€ เจธเจพเจฐเจฃเฉ€ เจฆเฉ€ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจ‡เจธ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจ…เจœเฉ‡ เจตเฉ€ เจธเจพเจฐเจฃเฉ€ เจคเฉ‹เจ‚ เจฌเฉ‡เจฒเฉ‹เฉœเฉ€ เจนเจฐ เจšเฉ€เจœเจผ เจจเฉ‚เฉฐ เจ–เจคเจฎ เจ•เจฐเจ•เฉ‡ เจธเจฟเจธเจŸเจฎ เจฆเฉ€ เจ•เจพเจฐเจ—เฉเจœเจผเจพเจฐเฉ€ เจจเฉ‚เฉฐ เจขเฉเจ•เจตเฉ€เจ‚ เจธเฉ€เจฎเจพเจตเจพเจ‚ 'เจคเฉ‡ เจตเจพเจชเจธ เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเจพเจ‚เจ—เฉ‡ - เจ˜เฉฑเจŸเฉ‹ เจ˜เฉฑเจŸ "เจนเฉฑเจฅเฉ€เจ‚", เจ•เจฟเจ‰เจ‚เจ•เจฟ เจตเฉˆเจ•เจฟเจŠเจฎ เจนเจพเจฐ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค

เจ‡เจธ เจจเฉ‚เฉฐ เจนเฉ‹เจฐ เจธเจชเฉฑเจธเจผเจŸ เจ•เจฐเจจ เจฒเจˆ, เจ†เจ“ เจ‡เฉฑเจ• เจฌเจซเจฐ เจŸเฉ‡เจฌเจฒ เจฆเฉ‡ เจ•เฉ‡เจธ เจฆเฉ€ เจ‰เจฆเจพเจนเจฐเจจ เจตเฉ‡เจ–เฉ€เจเฅค เจญเจพเจต, INSERT/DELETE เจฆเจพ เจ‡เฉฑเจ• เจตเฉฑเจกเจพ เจชเฉเจฐเจตเจพเจน เจนเฉเฉฐเจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ•เจˆ เจตเจพเจฐ เจธเจพเจฐเจฃเฉ€ เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจ–เจพเจฒเฉ€ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจชเจฐ เจœเฉ‡ เจ‡เจน เจ–เจพเจฒเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ, เจคเจพเจ‚ เจธเจพเจจเฉ‚เฉฐ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ เจ‡เจธเจฆเฉ€ เจฎเฉŒเจœเฉ‚เจฆเจพ เจธเจฎเฉฑเจ—เจฐเฉ€ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเฉ‹.

#0: เจธเจฅเจฟเจคเฉ€ เจฆเจพ เจฎเฉเจฒเจพเจ‚เจ•เจฃ เจ•เจฐเจจเจพ

เจ‡เจน เจธเจชเฉฑเจธเจผเจŸ เจนเฉˆ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจนเจฐ เจ“เจชเจฐเฉ‡เจธเจผเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจตเฉ€ เจŸเฉ‡เจฌเจฒ เจฆเฉ‡ เจจเจพเจฒ เจ•เฉเจ เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจชเจฐ เจ‡เจน เจฌเจนเฉเจค เจœเจผเจฟเจ†เจฆเจพ เจ…เจฐเจฅ เจจเจนเฉ€เจ‚ เจฐเฉฑเจ–เจฆเจพ - เจฎเฉ‡เจจเจŸเฉ‡เจจเฉˆเจ‚เจธ เจ“เจตเจฐเจนเฉˆเฉฑเจก เจธเจชเจธเจผเจŸ เจคเฉŒเจฐ 'เจคเฉ‡ เจจเจฟเจธเจผเจพเจจเจพ เจธเจตเจพเจฒเจพเจ‚ เจฆเฉ‡ เจฅเฉเจฐเจฐเฉ‚เจชเฉเจŸ เจคเฉ‹เจ‚ เจตเฉฑเจง เจนเฉ‹เจตเฉ‡เจ—เจพเฅค

เจ†เจ“ เจฎเจพเจชเจฆเฉฐเจก เจคเจฟเจ†เจฐ เจ•เจฐเฉ€เจ - "เจ‡เจน เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเจพ เจธเจฎเจพเจ‚ เจนเฉˆ" เจœเฉ‡เจ•เจฐ:

  • เจตเฉˆเจ•เจฟเจŠเจฎ เจจเฉ‚เฉฐ เจ•เจพเจซเฉ€ เจธเจฎเจพเจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจฒเจพเจ‚เจš เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€
    เจธเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจญเจพเจฐเฉ€ เจฌเฉ‹เจ เจฆเฉ€ เจ‰เจฎเฉ€เจฆ เจนเฉˆ, เจ‡เจธ เจฒเจˆ เจ‡เจธ เจจเฉ‚เฉฐ เจนเฉ‹เจฃ เจฆเจฟเจ“ 60 เจธเจ•เจฟเฉฐเจŸ เจชเจฟเจ›เจฒเฉ‡ [เจ†เจŸเฉ‹] เจตเฉˆเจ•เจฟเจŠเจฎ เจคเฉ‹เจ‚เฅค
  • เจญเฉŒเจคเจฟเจ• เจธเจพเจฐเจฃเฉ€ เจฆเจพ เจ†เจ•เจพเจฐ เจŸเฉ€เจšเฉ‡ เจคเฉ‹เจ‚ เจตเฉฑเจกเจพ เจนเฉˆ
    เจšเจฒเฉ‹ เจ‡เจธเจจเฉ‚เฉฐ เจ˜เฉฑเจŸเฉ‹-เจ˜เฉฑเจŸ เจ†เจ•เจพเจฐ เจฆเฉ‡ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจชเฉฐเจจเจฟเจ†เจ‚ เจฆเฉ€ เจธเฉฐเจ–เจฟเจ† (8KB เจฌเจฒเจพเจ•) เจฆเฉ‡ เจฆเฉเฉฑเจ—เจฃเฉ‡ เจตเจœเฉ‹เจ‚ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจ•เจฐเฉ€เจ - เจนเฉ€เจช เจฒเจˆ 1 blk + เจนเจฐเฉ‡เจ• เจธเฉ‚เจšเจ•เจพเจ‚เจ• เจฒเจˆ 1 blk - เจธเฉฐเจญเจพเจตเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจ–เจพเจฒเฉ€ เจŸเฉ‡เจฌเจฒ เจฒเจˆเฅค เจœเฉ‡ เจ…เจธเฉ€เจ‚ เจ‰เจฎเฉ€เจฆ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจกเฉ‡เจŸเจพ เจฆเฉ€ เจ‡เฉฑเจ• เจจเจฟเจธเจผเจšเจฟเจค เจฎเจพเจคเจฐเจพ เจนเจฎเฉ‡เจธเจผเจพ "เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡" เจฌเจซเจฐ เจตเจฟเฉฑเจš เจฐเจนเฉ‡เจ—เฉ€, เจคเจพเจ‚ เจ‡เจธ เจซเจพเจฐเจฎเฉ‚เจฒเฉ‡ เจจเฉ‚เฉฐ เจฌเจฆเจฒเจฃเจพ เจ‰เจšเจฟเจค เจนเฉˆเฅค

เจชเฉเจธเจผเจŸเฉ€เจ•เจฐเจจ เจฌเฉ‡เจจเจคเฉ€

SELECT
  relpages
, ((
    SELECT
      count(*)
    FROM
      pg_index
    WHERE
      indrelid = cl.oid
  ) + 1) << 13 size_norm -- ั‚ัƒั‚ ะฟั€ะฐะฒะธะปัŒะฝะตะต ะดะตะปะฐั‚ัŒ * current_setting('block_size')::bigint, ะฝะพ ะบั‚ะพ ะผะตะฝัะตั‚ ั€ะฐะทะผะตั€ ะฑะปะพะบะฐ?..
, pg_total_relation_size(oid) size
, coalesce(extract('epoch' from (now() - greatest(
    pg_stat_get_last_vacuum_time(oid)
  , pg_stat_get_last_autovacuum_time(oid)
  ))), 1 << 30) vaclag
FROM
  pg_class cl
WHERE
  oid = $1::regclass -- tbl
LIMIT 1;

relpages | size_norm | size    | vaclag
-------------------------------------------
       0 |     24576 | 1105920 | 3392.484835

#1: เจ…เจœเฉ‡ เจตเฉ€ เจตเฉˆเจ•เจฟเจŠเจฎ

เจ…เจธเฉ€เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจจเจนเฉ€เจ‚ เจœเจพเจฃ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ•เฉ€ เจ•เฉ‹เจˆ เจธเจฎเจพเจจเฉฐเจคเจฐ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจธเจพเจกเฉ‡ เจจเจพเจฒ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจคเฉŒเจฐ 'เจคเฉ‡ เจฆเจ–เจฒ เจฆเฉ‡ เจฐเจนเฉ€ เจนเฉˆ - เจ…เจธเจฒ เจตเจฟเฉฑเจš เจ‡เจน เจธเจผเฉเจฐเฉ‚ เจนเฉ‹เจฃ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจ•เจฟเฉฐเจจเฉ‡ เจฐเจฟเจ•เจพเจฐเจก "เจชเฉเจฐเจพเจฃเฉ‡" เจนเฉ‹ เจ—เจ เจนเจจเฅค เจ‡เจธ เจฒเจˆ, เจœเจฆเฉ‹เจ‚ เจ…เจธเฉ€เจ‚ เจ•เจฟเจธเฉ‡ เจตเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจŸเฉ‡เจฌเจฒ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจ•เจฐเจจ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจ•เจฟเจธเฉ‡ เจตเฉ€ เจธเจฅเจฟเจคเฉ€ เจตเจฟเฉฑเจš, เจธเจพเจจเฉ‚เฉฐ เจชเจนเจฟเจฒเจพเจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ เจตเฉˆเจ•เฉ‚เจฎ - เจตเฉˆเจ•เจฟเจŠเจฎ เจซเฉเจฒ เจฆเฉ‡ เจ‰เจฒเจŸ, เจ‡เจน เจฐเฉ€เจก-เจฐเจพเจˆเจŸ เจกเฉ‡เจŸเจพ เจฆเฉ‡ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจตเจพเจฒเฉ€เจ†เจ‚ เจธเจฎเจพเจจเจพเจ‚เจคเจฐ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ†เจตเจพเจ‚ เจตเจฟเฉฑเจš เจฆเจ–เจผเจฒ เจจเจนเฉ€เจ‚ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค

เจ‡เจธ เจฆเฉ‡ เจจเจพเจฒ เจนเฉ€, เจ‡เจน เจ‰เจนเจจเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจœเจผเจฟเจ†เจฆเจพเจคเจฐ เจšเฉ€เจœเจผเจพเจ‚ เจจเฉ‚เฉฐ เจคเฉเจฐเฉฐเจค เจธเจพเจซเจผ เจ•เจฐ เจธเจ•เจฆเจพ เจนเฉˆ เจœเฉ‹ เจ…เจธเฉ€เจ‚ เจนเจŸเจพเจ‰เจฃเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจนเจพเจ‚, เจ…เจคเฉ‡ เจ‡เจธ เจŸเฉ‡เจฌเจฒ 'เจคเฉ‡ เจฌเจพเจ…เจฆ เจฆเฉ‡ เจธเจตเจพเจฒ เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจœเจพเจฃเจ—เฉ‡ "เจ—เจฐเจฎ เจ•เฉˆเจธเจผ" เจฆเฉเจ†เจฐเจพ, เจœเฉ‹ เจ‰เจนเจจเจพเจ‚ เจฆเฉ€ เจฎเจฟเจ†เจฆ เจจเฉ‚เฉฐ เจ˜เจŸเจพ เจฆเฉ‡เจตเฉ‡เจ—เจพ - เจ…เจคเฉ‡, เจ‡เจธเจฒเจˆ, เจธเจพเจกเฉ‡ เจธเจฐเจตเจฟเจธเจฟเฉฐเจ— เจŸเฉเจฐเจพเจ‚เจœเฉˆเจ•เจธเจผเจจ เจฆเฉเจ†เจฐเจพ เจฆเฉ‚เจœเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจฌเจฒเจพเจ• เจ•เจฐเจจ เจฆเจพ เจ•เฉเฉฑเจฒ เจธเจฎเจพเจ‚เฅค

#2: เจ•เฉ€ เจ•เฉ‹เจˆ เจ˜เจฐ เจนเฉˆ?

เจ†เจ‰ เจœเจพเจ‚เจš เจ•เจฐเฉ€เจ เจ•เจฟ เจ•เฉ€ เจธเจพเจฐเจฃเฉ€ เจตเจฟเฉฑเจš เจ•เฉเจ เจตเฉ€ เจนเฉˆ:

TABLE tbl LIMIT 1;

เจœเฉ‡เจ•เจฐ เจ‡เฉฑเจ• เจตเฉ€ เจฐเจฟเจ•เจพเจฐเจก เจจเจนเฉ€เจ‚ เจฌเจšเจฟเจ† เจนเฉˆ, เจคเจพเจ‚ เจ…เจธเฉ€เจ‚ เจธเจฟเจฐเจซเจผ เจ•เจฐ เจ•เฉ‡ เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— 'เจคเฉ‡ เจฌเจนเฉเจค เจ•เฉเจ เจฌเจšเจพ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจธเฉฑเจšเจพเจˆ:

เจ‡เจน เจนเจฐเฉ‡เจ• เจŸเฉ‡เจฌเจฒ เจฒเจˆ เจฌเจฟเจจเจพเจ‚ เจธเจผเจฐเจค DELETE เจ•เจฎเจพเจ‚เจก เจตเจพเจ‚เจ— เจ•เฉฐเจฎ เจ•เจฐเจฆเจพ เจนเฉˆ, เจชเจฐ เจ‡เจน เจฌเจนเฉเจค เจคเฉ‡เจœเจผ เจนเฉˆ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เจน เจ…เจธเจฒ เจตเจฟเฉฑเจš เจŸเฉ‡เจฌเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจธเจ•เฉˆเจจ เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, เจ‡เจน เจคเฉเจฐเฉฐเจค เจกเจฟเจธเจ• เจธเจชเฉ‡เจธ เจจเฉ‚เฉฐ เจ–เจพเจฒเฉ€ เจ•เจฐ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจ‡เจธ เจฒเจˆ เจฌเจพเจ…เจฆ เจตเจฟเฉฑเจš เจตเฉˆเจ•เจฟเจŠเจฎ เจ“เจชเจฐเฉ‡เจธเจผเจจ เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจˆ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค

เจ•เฉ€ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจŸเฉ‡เจฌเจฒ เจ•เฉเจฐเจฎ เจ•เจพเจŠเจ‚เจŸเจฐ (เจฐเฉ€เจธเจŸเจพเจฐเจŸ เจ†เจˆเจกเฉˆเจ‚เจŸเจฟเจŸเฉ€) เจจเฉ‚เฉฐ เจฐเฉ€เจธเฉˆเจŸ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจ‡เจน เจซเฉˆเจธเจฒเจพ เจคเฉเจนเจพเจกเฉ‡ 'เจคเฉ‡ เจจเจฟเจฐเจญเจฐ เจ•เจฐเจฆเจพ เจนเฉˆเฅค

#3: เจนเจฐ เจ•เฉ‹เจˆ - เจตเจพเจฐเฉ€ เจฒเจ“!

เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจฌเจนเฉเจค เจนเฉ€ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจตเจพเจฒเฉ‡ เจฎเจพเจนเฉŒเจฒ เจตเจฟเฉฑเจš เจ•เฉฐเจฎ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจœเจฆเฉ‹เจ‚ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจฅเฉ‡ เจ‡เจน เจœเจพเจ‚เจš เจ•เจฐ เจฐเจนเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจธเจพเจฐเจฃเฉ€ เจตเจฟเฉฑเจš เจ•เฉ‹เจˆ เจเจ‚เจŸเจฐเฉ€เจ†เจ‚ เจจเจนเฉ€เจ‚ เจนเจจ, เจ•เจฟเจธเฉ‡ เจจเฉ‡ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจ‰เฉฑเจฅเฉ‡ เจ•เฉเจ เจฒเจฟเจ–เจฟเจ† เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆเฅค เจธเจพเจจเฉ‚เฉฐ เจ‡เจน เจœเจพเจฃเจ•เจพเจฐเฉ€ เจจเจนเฉ€เจ‚ เจ—เฉเจ†เจ‰เจฃเฉ€ เจšเจพเจนเฉ€เจฆเฉ€, เจคเจพเจ‚ เจ•เฉ€? เจ‡เจน เจธเจนเฉ€ เจนเฉˆ, เจธเจพเจจเฉ‚เฉฐ เจ‡เจน เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจ•เจฟ เจ•เฉ‹เจˆ เจตเฉ€ เจ‡เจธ เจจเฉ‚เฉฐ เจฏเจ•เฉ€เจจเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจฒเจฟเจ– เจจเจพ เจธเจ•เฉ‡เฅค

เจ…เจœเจฟเจนเจพ เจ•เจฐเจจ เจฒเจˆ เจธเจพเจจเฉ‚เฉฐ เจฏเฉ‹เจ— เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจ—เฉฐเจญเฉ€เจฐ-เจธเจพเจกเฉ‡ เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจฒเจˆ เจ…เจฒเฉฑเจ—-เจฅเจฒเฉฑเจ— (เจนเจพเจ‚, เจ‡เฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚) เจ…เจคเฉ‡ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ "เจ•เฉฐเจŸ" เจจเจพเจฒ เจฒเจพเจ• เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚:

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;

เจฌเจฒเจพเจ•เจฟเฉฐเจ— เจฆเจพ เจ‡เจน เจชเฉฑเจงเจฐ เจ‰เจนเจจเจพเจ‚ เจ“เจชเจฐเฉ‡เจธเจผเจจเจพเจ‚ เจฆเฉเจ†เจฐเจพ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ เจœเฉ‹ เจ…เจธเฉ€เจ‚ เจ‡เจธ 'เจคเฉ‡ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚เฅค

#4: เจนเจฟเฉฑเจคเจพเจ‚ เจฆเจพ เจŸเจ•เจฐเจพเจ…

เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจฅเฉ‡ เจ†เจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ เจšเจฟเฉฐเจจเฉเจน เจจเฉ‚เฉฐ "เจฒเจพเจ•" เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚ - เจœเฉ‡ เจ•เฉ‹เจˆ เจ‰เจธ เจธเจฎเฉ‡เจ‚ เจ‡เจธ 'เจคเฉ‡ เจธเจฐเจ—เจฐเจฎ เจธเฉ€, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ‡เจธ เจคเฉ‹เจ‚ เจชเฉœเฉเจนเจจเจพ? เจ…เจธเฉ€เจ‚ เจ‡เจธ เจฌเจฒเจพเจ• เจฆเฉ‡ เจœเจพเจฐเฉ€ เจนเฉ‹เจฃ เจฆเฉ€ เจ‰เจกเฉ€เจ• เจตเจฟเฉฑเจš "เจฒเจŸเจ•" เจœเจพเจตเจพเจ‚เจ—เฉ‡, เจ…เจคเฉ‡ เจนเฉ‹เจฐ เจœเฉ‹ เจชเฉœเฉเจนเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจจ เจธเจพเจกเฉ‡ เจตเจฟเฉฑเจš เจ†เจ‰เจฃเจ—เฉ‡...

เจ…เจœเจฟเจนเจพ เจนเฉ‹เจฃ เจคเฉ‹เจ‚ เจฐเฉ‹เจ•เจฃ เจฒเจˆ, เจ…เจธเฉ€เจ‚ "เจ†เจชเจฃเฉ‡ เจ†เจช เจจเฉ‚เฉฐ เจ•เฉเจฐเจฌเจพเจจ เจ•เจฐ เจฆเฉ‡เจตเจพเจ‚เจ—เฉ‡" - เจœเฉ‡ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจจเจฟเจธเจผเจšเจค (เจธเจตเฉ€เจ•เจพเจฐเจจเจฏเฉ‹เจ— เจคเฉŒเจฐ 'เจคเฉ‡ เจฅเฉ‹เฉœเฉ‡ เจธเจฎเฉ‡เจ‚ เจตเจฟเฉฑเจš) เจ‡เฉฑเจ• เจคเจพเจฒเจพ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจตเจฟเฉฑเจš เจ…เจธเจฎเจฐเฉฑเจฅ เจธเฉ€, เจคเจพเจ‚ เจธเจพเจจเฉ‚เฉฐ เจ…เจงเจพเจฐ เจคเฉ‹เจ‚ เจ‡เฉฑเจ• เจ…เจชเจตเจพเจฆ เจฎเจฟเจฒเฉ‡เจ—เจพ, เจชเจฐ เจ˜เฉฑเจŸเฉ‹ เจ˜เฉฑเจŸ เจ…เจธเฉ€เจ‚ เจ‡เจธ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจœเจผเจฟเจ†เจฆเจพ เจฆเจ–เจฒ เจจเจนเฉ€เจ‚ เจฆเฉ‡เจตเจพเจ‚เจ—เฉ‡เฅค เจนเฉ‹เจฐเฅค

เจ…เจœเจฟเจนเจพ เจ•เจฐเจจ เจฒเจˆ, เจธเฉˆเจธเจผเจจ เจตเฉ‡เจฐเฉ€เจเจฌเจฒ เจธเฉˆเฉฑเจŸ เจ•เจฐเฉ‹ lock_timeout (เจธเฉฐเจธเจ•เจฐเจฃ 9.3+ เจฒเจˆ) เจœเจพเจ‚/เจ…เจคเฉ‡ เจธเจŸเฉ‡เจŸเจฎเฉˆเจ‚เจŸ_เจŸเจพเจˆเจฎเจ†เจŠเจŸ. เจฏเจพเจฆ เจฐเฉฑเจ–เจฃ เจตเจพเจฒเฉ€ เจฎเฉเฉฑเจ– เจ—เฉฑเจฒ เจ‡เจน เจนเฉˆ เจ•เจฟ เจธเจŸเฉ‡เจŸเจฎเฉˆเจ‚เจŸ_เจŸเจพเจˆเจฎเจ†เจ‰เจŸ เจฎเฉเฉฑเจฒ เจธเจฟเจฐเจซ เจ…เจ—เจฒเฉ‡ เจธเจŸเฉ‡เจŸเจฎเฉˆเจ‚เจŸ เจคเฉ‹เจ‚ เจฒเจพเจ—เฉ‚ เจนเฉเฉฐเจฆเจพ เจนเฉˆเฅค เจฏเจพเจจเฉ€ เจ—เจฒเฉ‚เจ‡เฉฐเจ— เจตเจฟเฉฑเจš เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ - เจ•เฉฐเจฎ เจจเจนเฉ€เจ‚ เจ•เจฐเฉ‡เจ—เจพ:

SET statement_timeout = ...;LOCK TABLE ...;

เจตเฉ‡เจฐเฉ€เจเจฌเจฒ เจฆเฉ‡ "เจชเฉเจฐเจพเจฃเฉ‡" เจฎเฉเฉฑเจฒ เจจเฉ‚เฉฐ เจฌเจพเจ…เจฆ เจตเจฟเฉฑเจš เจฌเจนเจพเจฒ เจ•เจฐเจจ เจจเจพเจฒ เจจเจœเจฟเฉฑเจ เจฃ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจซเจพเจฐเจฎ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจธเจฅเจพเจจเจ• เจธเฉˆเฉฑเจŸ เจ•เจฐเฉ‹, เจœเฉ‹ เจฎเฉŒเจœเฉ‚เจฆเจพ เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจฒเจˆ เจธเฉˆเจŸเจฟเฉฐเจ— เจฆเฉ‡ เจฆเจพเจ‡เจฐเฉ‡ เจจเฉ‚เฉฐ เจธเฉ€เจฎเจฟเจค เจ•เจฐเจฆเจพ เจนเฉˆเฅค

เจธเจพเจจเฉ‚เฉฐ เจฏเจพเจฆ เจนเฉˆ เจ•เจฟ เจธเจŸเฉ‡เจŸเจฎเฉˆเจ‚เจŸ_เจŸเจพเจˆเจฎเจ†เจ‰เจŸ เจธเจพเจฐเฉ€เจ†เจ‚ เจ…เจ—เจฒเฉ€เจ†เจ‚ เจฌเฉ‡เจจเจคเฉ€เจ†เจ‚ 'เจคเฉ‡ เจฒเจพเจ—เฉ‚ เจนเฉเฉฐเจฆเจพ เจนเฉˆ เจคเจพเจ‚ เจœเฉ‹ เจธเจพเจฐเจฃเฉ€ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจธเจพเจฐเจพ เจกเฉ‡เจŸเจพ เจนเฉ‹เจฃ 'เจคเฉ‡ เจŸเฉเจฐเจพเจ‚เจœเฉˆเจ•เจธเจผเจจ เจ…เจธเจตเฉ€เจ•เจพเจฐเจจเจฏเฉ‹เจ— เจฎเฉเฉฑเจฒเจพเจ‚ เจคเฉฑเจ• เจจเจนเฉ€เจ‚ เจตเจง เจธเจ•เฉ‡เฅค

#5: เจกเจพเจŸเจพ เจ•เจพเจชเฉ€ เจ•เจฐเฉ‹

เจœเฉ‡เจ•เจฐ เจธเจพเจฐเจฃเฉ€ เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจ–เจพเจฒเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ, เจคเจพเจ‚ เจ‡เฉฑเจ• เจธเจนเจพเจ‡เจ• เจ…เจธเจฅเจพเจˆ เจธเจพเจฐเจฃเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ เจฎเฉเฉœ-เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจจเจพ เจนเฉ‹เจตเฉ‡เจ—เจพ:

CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;

เจฆเจธเจคเจ–เจค เจ•เจฎเจฟเจŸ เจกเฉเจฐเฉŒเจช 'เจคเฉ‡ เจฆเจพ เจฎเจคเจฒเจฌ เจนเฉˆ เจ•เจฟ เจœเจฟเจธ เจธเจฎเฉ‡เจ‚ เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจ–เจคเจฎ เจนเฉเฉฐเจฆเจพ เจนเฉˆ, เจ…เจธเจฅเจพเจˆ เจธเจพเจฐเจฃเฉ€ เจฎเฉŒเจœเฉ‚เจฆ เจจเจนเฉ€เจ‚ เจฐเจนเจฟ เจœเจพเจตเฉ‡เจ—เฉ€, เจ…เจคเฉ‡ เจ•เจจเฉˆเจ•เจธเจผเจจ เจฆเฉ‡ เจธเฉฐเจฆเจฐเจญ เจตเจฟเฉฑเจš เจ‡เจธเจจเฉ‚เฉฐ เจนเฉฑเจฅเฉ€เจ‚ เจฎเจฟเจŸเจพเจ‰เจฃ เจฆเฉ€ เจ•เฉ‹เจˆ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค

เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ‡เจน เจฎเฉฐเจจเจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ‡เฉฑเจฅเฉ‡ เจฌเจนเฉเจค เจธเจพเจฐเจพ "เจฒเจพเจˆเจต" เจกเฉ‡เจŸเจพ เจจเจนเฉ€เจ‚ เจนเฉˆ, เจ‡เจน เจ•เจพเจฐเจตเจพเจˆ เจฌเจนเฉเจค เจคเฉ‡เจœเจผเฉ€ เจจเจพเจฒ เจนเฉ‹เจฃเฉ€ เจšเจพเจนเฉ€เจฆเฉ€ เจนเฉˆเฅค

เจ–เฉˆเจฐ, เจ‡เจน เจธเจญ เจ•เฉเจ เจนเฉˆ! เจฒเฉˆเจฃ-เจฆเฉ‡เจฃ เจจเฉ‚เฉฐ เจชเฉ‚เจฐเจพ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจจเจพ เจญเฉเฉฑเจฒเฉ‹ เจตเจฟเจธเจผเจฒเฉ‡เจธเจผเจฃ เจšเจฒเจพเจ“ เจœเฉ‡ เจฒเฉ‹เฉœ เจนเฉ‹เจตเฉ‡ เจคเจพเจ‚ เจธเจพเจฐเจฃเฉ€ เจฆเฉ‡ เจ…เฉฐเจ•เฉœเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจ†เจฎ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆเฅค

เจ…เฉฐเจคเจฟเจฎ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจ‡เจ•เฉฑเจ เจพ เจ•เจฐเจจเจพ

เจ…เจธเฉ€เจ‚ เจ‡เจธ "เจธเฉ‚เจกเฉ‹-เจชเจพเจˆเจฅเจจ" เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚:

# ัะพะฑะธั€ะฐะตะผ ัั‚ะฐั‚ะธัั‚ะธะบัƒ ั ั‚ะฐะฑะปะธั†ั‹
stat <-
  SELECT
    relpages
  , ((
      SELECT
        count(*)
      FROM
        pg_index
      WHERE
        indrelid = cl.oid
    ) + 1) << 13 size_norm
  , pg_total_relation_size(oid) size
  , coalesce(extract('epoch' from (now() - greatest(
      pg_stat_get_last_vacuum_time(oid)
    , pg_stat_get_last_autovacuum_time(oid)
    ))), 1 << 30) vaclag
  FROM
    pg_class cl
  WHERE
    oid = $1::regclass -- table_name
  LIMIT 1;

# ั‚ะฐะฑะปะธั†ะฐ ะฑะพะปัŒัˆะต ั†ะตะปะตะฒะพะณะพ ั€ะฐะทะผะตั€ะฐ ะธ VACUUM ะฑั‹ะป ะดะฐะฒะฝะพ
if stat.size > 2 * stat.size_norm and stat.vaclag is None or stat.vaclag > 60:
  -> VACUUM %table;
  try:
    -> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    # ะฟั‹ั‚ะฐะตะผัั ะทะฐั…ะฒะฐั‚ะธั‚ัŒ ะผะพะฝะพะฟะพะปัŒะฝัƒัŽ ะฑะปะพะบะธั€ะพะฒะบัƒ ั ะฟั€ะตะดะตะปัŒะฝั‹ะผ ะฒั€ะตะผะตะฝะตะผ ะพะถะธะดะฐะฝะธั 1s
    -> SET LOCAL statement_timeout = '1s'; SET LOCAL lock_timeout = '1s';
    -> LOCK TABLE %table IN ACCESS EXCLUSIVE MODE;
    # ะฝะฐะดะพ ัƒะฑะตะดะธั‚ัŒัั ะฒ ะฟัƒัั‚ะพั‚ะต ั‚ะฐะฑะปะธั†ั‹ ะฒะฝัƒั‚ั€ะธ ั‚ั€ะฐะฝะทะฐะบั†ะธะธ ั ะฑะปะพะบะธั€ะพะฒะบะพะน
    row <- TABLE %table LIMIT 1;
    # ะตัะปะธ ะฒ ั‚ะฐะฑะปะธั†ะต ะฝะตั‚ ะฝะธ ะพะดะฝะพะน "ะถะธะฒะพะน" ะทะฐะฟะธัะธ - ะพั‡ะธั‰ะฐะตะผ ะตะต ะฟะพะปะฝะพัั‚ัŒัŽ, ะฒ ะฟั€ะพั‚ะธะฒะฝะพะผ ัะปัƒั‡ะฐะต - "ะฟะตั€ะตะฒัั‚ะฐะฒะปัะตะผ" ะฒัะต ะทะฐะฟะธัะธ ั‡ะตั€ะตะท ะฒั€ะตะผะตะฝะฝัƒัŽ ั‚ะฐะฑะปะธั†ัƒ
    if row is None:
      -> TRUNCATE TABLE %table RESTART IDENTITY;
    else:
      # ัะพะทะดะฐะตะผ ะฒั€ะตะผะตะฝะฝัƒัŽ ั‚ะฐะฑะปะธั†ัƒ ั ะดะฐะฝะฝั‹ะผะธ ั‚ะฐะฑะปะธั†ั‹-ะพั€ะธะณะธะฝะฐะปะฐ
      -> CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE %table;
      # ะพั‡ะธั‰ะฐะตะผ ะพั€ะธะณะธะฝะฐะป ะฑะตะท ัะฑั€ะพัะฐ ะฟะพัะปะตะดะพะฒะฐั‚ะตะปัŒะฝะพัั‚ะธ
      -> TRUNCATE TABLE %table;
      # ะฒัั‚ะฐะฒะปัะตะผ ะฒัะต ัะพั…ั€ะฐะฝะตะฝะฝั‹ะต ะฒะพ ะฒั€ะตะผะตะฝะฝะพะน ั‚ะฐะฑะปะธั†ะต ะดะฐะฝะฝั‹ะต ะพะฑั€ะฐั‚ะฝะพ
      -> INSERT INTO %table TABLE _tmp_swap;
    -> COMMIT;
  except Exception as e:
    # ะตัะปะธ ะผั‹ ะฟะพะปัƒั‡ะธะปะธ ะพัˆะธะฑะบัƒ, ะฝะพ ัะพะตะดะธะฝะตะฝะธะต ะฒัะต ะตั‰ะต "ะถะธะฒะพ" - ัะปะพะฒะธะปะธ ั‚ะฐะนะผะฐัƒั‚
    if not isinstance(e, InterfaceError):
      -> ROLLBACK;

เจ•เฉ€ เจฆเฉ‚เจœเฉ€ เจตเจพเจฐ เจกเฉ‡เจŸเจพ เจฆเฉ€ เจจเจ•เจฒ เจจเจพ เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจนเฉˆ?เจธเจฟเจงเจพเจ‚เจคเจ• เจคเฉŒเจฐ 'เจคเฉ‡, เจ‡เจน เจธเฉฐเจญเจต เจนเฉˆ เจœเฉ‡เจ•เจฐ เจธเจพเจฐเจฃเฉ€ เจฆเจพ oid เจ–เฉเจฆ BL เจธเจพเจˆเจก เจœเจพเจ‚ FK DB เจชเจพเจธเฉ‡ เจคเฉ‹เจ‚ เจ•เจฟเจธเฉ‡ เจนเฉ‹เจฐ เจ—เจคเฉ€เจตเจฟเจงเฉ€เจ†เจ‚ เจจเจพเจฒ เจจเจนเฉ€เจ‚ เจœเฉเฉœเจฟเจ† เจนเฉ‹เจ‡เจ† เจนเฉˆ:

CREATE TABLE _swap_%table(LIKE %table INCLUDING ALL);
INSERT INTO _swap_%table TABLE %table;
DROP TABLE %table;
ALTER TABLE _swap_%table RENAME TO %table;

เจ†เจ‰ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจธเจฐเฉ‹เจค เจธเจพเจฐเจฃเฉ€ 'เจคเฉ‡ เจšเจฒเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ เจฎเฉˆเจŸเฉเจฐเจฟเจ•เจธ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚:

VACUUM tbl;
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  SET LOCAL statement_timeout = '1s'; SET LOCAL lock_timeout = '1s';
  LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;
  CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;
  TRUNCATE TABLE tbl;
  INSERT INTO tbl TABLE _tmp_swap;
COMMIT;

relpages | size_norm | size   | vaclag
-------------------------------------------
       0 |     24576 |  49152 | 32.705771

เจธเจญ เจ•เฉเจ เจ•เฉฐเจฎ เจ•เฉ€เจคเจพ! เจธเจพเจฐเจฃเฉ€ 50 เจตเจพเจฐ เจธเฉเฉฐเจ—เฉœ เจ—เจˆ เจนเฉˆ เจ…เจคเฉ‡ เจธเจพเจฐเฉ‡ เจ…เฉฑเจชเจกเฉ‡เจŸ เจฆเฉเจฌเจพเจฐเจพ เจคเฉ‡เจœเจผเฉ€ เจจเจพเจฒ เจšเฉฑเจฒ เจฐเจนเฉ‡ เจนเจจเฅค

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹