เชเชตเซ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเช เชนเซเชฏ เชเซ เชเซเชฏเชพเชฐเซ เชชเซเชฐเชพเชฅเชฎเชฟเช เชเซ เชตเชเชฐเชจเชพ เชเซเชทเซเชเชเชฎเชพเช เช เชฅเชตเชพ เชเซเช เช เชจเซเชฏ เช เชจเชจเซเชฏ เชธเซเชเชเชพเชเช, เชญเซเชฒเชจเซ เชเชพเชฐเชฃเซ, เชชเชนเซเชฒเชพเชฅเซ เช เช เชธเซเชคเชฟเชคเซเชตเชฎเชพเช เชฐเชนเซเชฒเชพ เชฐเซเชเซเชฐเซเชกเซเชธเชจเชพ เชธเชเชชเซเชฐเซเชฃ เชเซเชฒเซเชจเซเชธ เชงเชฐเชพเชตเซ เชเซ.

เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชเชพเชฒเชเซเชฐเชฎเชฟเช เชฎเซเชเซเชฐเชฟเชเชจเชพ เชฎเซเชฒเซเชฏเซ COPY เชธเซเชเซเชฐเซเชฎเชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ PostgreSQL เชชเชฐ เชฒเชเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เช
เชจเซ เชชเชเซ เช
เชเชพเชจเช เชจเชฟเชทเซเชซเชณเชคเชพ เชเชตเซ เชเซ, เช
เชจเซ เชเซเชเชฒเชพเช เชธเชเชชเซเชฐเซเชฃเชชเชฃเซ เชธเชฎเชพเชจ เชกเซเชเชพ เชซเชฐเซเชฅเซ เชเชตเซ เชเซ.
เชกเซเชเชพเชฌเซเชเชฎเชพเชเชฅเซ เชฌเชฟเชจเชเชฐเซเชฐเซ เชเซเชฒเซเชจเซเชธ เชเซเชตเซ เชฐเซเชคเซ เชฆเซเชฐ เชเชฐเชตเชพ?
เชเซเชฏเชพเชฐเซ เชชเซเชเซ เชฎเชฆเชฆเชฐเซเชช เชจ เชนเซเชฏ
เชธเซเชฅเซ เชธเชฐเชณ เชเชชเชพเชฏ เช เชเซ เชเซ เช เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซ เชถเชฐเซเชเชคเชฎเชพเช เช เชฌเชจเชคเซ เช เชเชเชพเชตเชตเซ. เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, PRIMARY KEY เชฒเชพเชเซ เชเชฐเซเชจเซ. เชชเชฐเชเชคเซ เชธเชเชเซเชฐเชนเชฟเชค เชกเซเชเชพเชจเซ เชฎเชพเชคเซเชฐเชพเชฎเชพเช เชตเชงเชพเชฐเซ เชเชฐเซเชฏเชพ เชตเชฟเชจเชพ เช เชนเชเชฎเซเชถเชพ เชถเชเซเชฏ เชจเชฅเซ.
เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชเซ เชธเซเชฐเซเชค เชธเชฟเชธเซเชเชฎเชจเซ เชเซเชเชธเชพเช เชกเซเชเชพเชฌเซเชเชฎเชพเช เชซเซเชฒเซเชกเชจเซ เชเซเชเชธเชพเช เชเชฐเชคเชพ เชตเชงเชพเชฐเซ เชนเซเชฏ:
metric | ts | data
--------------------------------------------------
cpu.busy | 2019-12-20 00:00:00 | {"value" : 12.34}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 10}
cpu.busy | 2019-12-20 00:00:01 | {"value" : 11.2}
cpu.busy | 2019-12-20 00:00:03 | {"value" : 15.7}
เชจเซเชเชงเซเชฏเซเช? 00:00:02 เชจเซ เชฌเชฆเชฒเซ, เชเชฃเชคเชฐเซ เชเช เชธเซเชเชจเซเชก เชชเชนเซเชฒเชพ ts เชกเซเชเชพเชฌเซเชเชฎเชพเช เชฐเซเชเซเชฐเซเชก เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชนเชคเซ, เชชเชฐเชเชคเซ เชตเซเชฏเชตเชนเชพเชฐเชฟเช เชฆเซเชทเซเชเชฟเชเซเชฃเชฅเซ เชคเซ เชธเชเชชเซเชฐเซเชฃเชชเชฃเซ เชฎเชพเชจเซเชฏ เชฐเชนเซ (เชเซเชตเชเซ, เชกเซเชเชพ เชฎเซเชฒเซเชฏเซ เช เชฒเช เชเซ!).
เช เชฒเชฌเชคเซเชค, เชคเซ เชเชฐเซ เชถเชเชพเชฏ เชเซ PK(เชฎเซเชเซเชฐเชฟเช, ts) โ เชชเชฃ เชชเชเซ เชเชชเชฃเชจเซ เชฎเชพเชจเซเชฏ เชกเซเชเชพ เชฎเชพเชเซ เชจเชฟเชตเซเชถ เชตเชฟเชฐเซเชงเชพเชญเชพเชธ เชฎเชณเชถเซ.
เชเชฐเซ เชถเชเชตเซ PK(เชฎเซเชเซเชฐเชฟเช, ts, เชกเซเชเชพ) - เชชเชฐเชเชคเซ เชเชจเชพเชฅเซ เชคเซเชจเซเช เชชเซเชฐเชฎเชพเชฃ เชเชฃเซเช เชตเชงเชถเซ, เชเซเชจเซ เชเชชเชฃเซ เชเชชเชฏเซเช เชเชฐเซเชถเซเช เชจเชนเซเช.
เชคเซเชฅเซ, เชธเซเชฅเซ เชธเชพเชเซ เชตเชฟเชเชฒเซเชช เช เชเซ เชเซ เชจเชฟเชฏเชฎเชฟเชค เชฌเชฟเชจ-เช เชจเชจเซเชฏ เช เชจเซเชเซเชฐเชฎเชฃเชฟเชเชพ เชฌเชจเชพเชตเชตเซ. (เชฎเซเชเซเชฐเชฟเช, เชเซเชเชธ) เช เชจเซ เชเซ เชธเชฎเชธเซเชฏเชพเช เชเชญเซ เชฅเชพเชฏ เชคเซ เชคเซเชจเซ เชธเชพเชฎเชจเซ เชเชฐเซ.
เชเซเชฒเซเชจ เชฏเซเชฆเซเชงเซ เชถเชฐเซ เชฅเช เชเชฏเชพ เชเซ.
เชเซเช เช เชเชธเซเชฎเชพเชค เชฅเชฏเซ, เช เชจเซ เชนเชตเซ เชเชชเชฃเซ เชเซเชฌเชฒ เชชเชฐเชฅเซ เชเซเชฒเซเชจ เชฐเซเชเซเชฐเซเชกเชจเซ เชจเชพเชถ เชเชฐเชตเซ เชชเชกเชถเซ.

เชเชพเชฒเซ เชชเซเชฐเชพเชฐเชเชญเชฟเช เชกเซเชเชพเชจเซเช เช
เชจเซเชเชฐเชฃ เชเชฐเซเช:
CREATE TABLE tbl(k text, v integer);
INSERT INTO tbl
VALUES
('a', 1)
, ('a', 3)
, ('b', 2)
, ('b', 2) -- oops!
, ('c', 3)
, ('c', 3) -- oops!!
, ('c', 3) -- oops!!
, ('d', 4)
, ('e', 5)
;เช เชนเซเช เชเชชเชฃเซ เชนเชพเชฅ เชคเซเชฐเชฃ เชตเชพเชฐ เชงเซเชฐเซเชเซเชฏเซ, Ctrl+V เช เชเชเซ เชเชฏเซเช, เช เชจเซ เช เชนเซเช เชคเซ เชเซ...
เชชเชนเซเชฒเชพ, เชเชพเชฒเซ เชธเชฎเชเซเช เชเซ เชเชชเชฃเซเช เชเซเชฌเชฒ เชเชฃเซเช เชฎเซเชเซเช เชนเซเช เชถเชเซ เชเซ, เชคเซเชฅเซ เชฌเชงเชพ เชเซเชฒเซเชจเซเชธ เชถเซเชงเซ เชเชพเชขเซเชฏเชพ เชชเชเซ, เชเชชเชฃเซ เชคเซเชฎเชจเซ เชเชพเชขเซ เชจเชพเชเชตเชพ เชฎเชพเชเซ เชถเชพเชฌเซเชฆเชฟเช เชฐเซเชคเซ "เชเชเชเชณเซ เชเชถเชพเชฐเซ" เชเชฐเชตเซ เชชเชกเชถเซ. เชเซเชเซเชเชธ เชฐเซเชเซเชฐเซเชกเซเชธ เชซเชฐเซเชฅเซ เชถเซเชงเซเชฏเชพ เชตเชฟเชจเชพ.
เช เชจเซ เชเชตเซ เชเช เชฐเซเชค เชเซ - เช เชเซ , เชเซเชเซเชเชธ เชฐเซเชเซเชฐเซเชกเชจเซ เชญเซเชคเชฟเช เชเชณเชเชเชฐเซเชคเชพ.
เชคเซ, เชธเซ เชชเซเชฐเชฅเชฎ, เชเชชเชฃเซ เชเซเชฌเชฒ เชชเชเชเซเชคเชฟเชจเซ เชธเชเชชเซเชฐเซเชฃ เชธเชพเชฎเชเซเชฐเซเชจเชพ เชเชงเชพเชฐเซ เชฐเซเชเซเชฐเซเชกเซเชธเชจเชพ CTID เชเชเชคเซเชฐเชฟเชค เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ. เชธเซเชฅเซ เชธเชฐเชณ เชตเชฟเชเชฒเซเชช เช เชเซ เชเซ เชเชเซ เชชเชเชเซเชคเชฟเชจเซ เชเซเชเซเชธเซเชเชฎเชพเช เชเชพเชธเซเช เชเชฐเซ:
SELECT
T::text
, array_agg(ctid) ctids
FROM
tbl T
GROUP BY
1;
t | ctids
---------------------------------
(e,5) | {"(0,9)"}
(d,4) | {"(0,8)"}
(c,3) | {"(0,5)","(0,6)","(0,7)"}
(b,2) | {"(0,3)","(0,4)"}
(a,3) | {"(0,2)"}
(a,1) | {"(0,1)"}
เชถเซเช เชเชพเชธเซเช เชจ เชเชฐเชตเซเช เชถเชเซเชฏ เชเซ?เชธเชฟเชฆเซเชงเชพเชเชคเชฎเชพเช, เชฎเซเชเชพเชญเชพเชเชจเชพ เชเชฟเชธเซเชธเชพเชเชฎเชพเช เชคเซ เชถเชเซเชฏ เชเซ. เชเซเชฏเชพเช เชธเซเชงเซ เชคเชฎเซ เช เชเซเชทเซเชเชเชฎเชพเช เชซเซเชฒเซเชกเซเชธเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชจเซเช เชถเชฐเซ เชจ เชเชฐเซ เชคเซเชฏเชพเช เชธเซเชงเซ เชธเชฎเชพเชจเชคเชพ เชตเชฟเชจเชพเชจเชพ เชชเซเชฐเชเชพเชฐเซ เชเชชเชฐเซเชเชฐ:
CREATE TABLE tbl(k text, v integer, x point);
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T;
-- ERROR: could not identify an equality operator for type tbl
เชเชนเชพ, เชเชชเชฃเซ เชคเชฐเชค เช เชเซเช เชถเชเซเช เชเซเช เชเซ เชเซ เชเชฐเซเชฎเชพเช เชเช เชเชฐเชคเชพเช เชตเชงเซ เชเชจเซเชเซเชฐเซ เชนเซเชฏ, เชคเซ เชคเซ เชฌเชงเชพ เชเซเชฒเซเชจเซเชธ เชเซ. เชเชพเชฒเซ เชซเชเซเชค เชคเซ เช เชฐเชพเชเซเช:
SELECT
unnest(ctids[2:])
FROM
(
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T::text
) T;unnest
------
(0,6)
(0,7)
(0,4)เชเซเชฎเชจเซ เชเซเชเชเซเช เชฒเชเชตเชพเชจเซเช เชเชฎเซ เชเซ เชคเซเชฎเชจเชพ เชฎเชพเชเซเชคเชฎเซ เชคเซเชจเซ เช เชฐเซเชคเซ เชชเชฃ เชฒเชเซ เชถเชเซ เชเซ:
SELECT
unnest((array_agg(ctid))[2:])
FROM
tbl T
GROUP BY
T::text;เช เชฎเชจเซ เชธเซเชฐเซเชฏเชฒเชพเชเชเซเชก เชธเซเชเซเชฐเชฟเชเชเชจเชพ เชฎเซเชฒเซเชฏเชฎเชพเช เชฐเชธ เชจ เชนเซเชตเชพเชฅเซ, เช เชฎเซ เชคเซเชจเซ เชธเชฌเชเซเชตเซเชฐเซเชจเชพเช เชชเชฐเชค เชเชฐเซเชฒเชพ เชเซเชฒเชฎเชฎเชพเชเชฅเซ เชเซเชกเซ เชฆเซเชงเซเช.
เช เชฎเชจเซ เชฎเชณเซเชฒเชพ เชธเซเชเชจเซ เชเชชเชฏเซเช DELETE เชจเซ เชเชฐเชพเชตเชตเชพเชจเซเช เชฌเชพเชเซ เชเซ:
DELETE FROM
tbl
WHERE
ctid = ANY(ARRAY(
SELECT
unnest(ctids[2:])
FROM
(
SELECT
array_agg(ctid) ctids
FROM
tbl T
GROUP BY
T::text
) T
)::tid[]);เชเชพเชฒเซ เชเชชเชฃเซ เชเชพเชคเชจเซ เชเชเชพเชธเซเช:

เชนเชพ, เชคเซ เชธเชพเชเซเช เชเซ: เช เชฎเชพเชฐเชพ 3 เชฐเซเชเซเชฐเซเชก เชธเชฎเชเซเชฐ เชเซเชทเซเชเชเชจเชพ เชเช เช Seq เชธเซเชเซเชจเชฎเชพเช เชชเชธเชเชฆ เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเชพ เชนเชคเชพ, เช เชจเซ เชกเซเชเชพ เชถเซเชงเชตเชพ เชฎเชพเชเซ Delete เชจเซเชกเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซ เชนเชคเซ. เชเชฟเชก เชธเซเชเซเชจ เชธเชพเชฅเซ เชธเชฟเชเชเชฒ เชชเชพเชธ:
-> Tid Scan on tbl (actual time=0.050..0.051 rows=3 loops=1)
TID Cond: (ctid = ANY ($0))เชเซ เชคเชฎเซ เชเชฃเชพ เชฌเชงเชพ เชฐเซเชเซเชฐเซเชก เชธเชพเชซ เชเชฐเซเชฏเชพ เชนเซเชฏ, .
เชเชพเชฒเซ เชเช เชฎเซเชเซเช เชเซเชฌเชฒ เช เชจเซ เชตเชงเซ เชธเชเชเซเชฏเชพเชฎเชพเช เชกเซเชชเซเชฒเชฟเชเซเชเซเชธ เชธเชพเชฅเซ เชคเชชเชพเชธเซเช:
TRUNCATE TABLE tbl;
INSERT INTO tbl
SELECT
chr(ascii('a'::text) + (random() * 26)::integer) k -- a..z
, (random() * 100)::integer v -- 0..99
FROM
generate_series(1, 10000) i; 
เชคเซเชฅเซ, เชชเชฆเซเชงเชคเชฟ เชธเชซเชณเชคเชพเชชเซเชฐเซเชตเช เชเชพเชฐเซเชฏ เชเชฐเซ เชเซ, เชชเชฐเชเชคเซ เชคเซเชจเซ เชเชชเชฏเซเช เชฅเซเชกเซ เชธเชพเชตเชงเชพเชจเซ เชธเชพเชฅเซ เชเชฐเชตเซ เชเซเชเช. เชเชพเชฐเชฃ เชเซ เชฆเชฐเซเช เชกเชฟเชฒเซเช เชเชฐเซเชฒเชพ เชฐเซเชเซเชฐเซเชก เชฎเชพเชเซ, Tid Scan เชฎเชพเช เชเช เชกเซเชเชพ เชชเซเช เช
เชจเซ Delete เชฎเชพเช เชเช เชกเซเชเชพ เชชเซเช เชตเชพเชเชเชตเชพเชฎเชพเช เชเชตเซ เชเซ.
เชธเซเชฐเซเชธ: www.habr.com
