рдЕрд╢реА рдкрд░рд┐рд╕реНрдерд┐рддреА рдЕрд╕рддреЗ рдЬреЗрд╡реНрд╣рд╛ рдкреНрд░рд╛рдердорд┐рдХ рдХрд┐рд▓реНрд▓реАрд╢рд┐рд╡рд╛рдп рдЯреЗрдмрд▓рд╡рд░ рдХрд┐рдВрд╡рд╛ рдЗрддрд░ рдХрд╛рд╣реА рдЕрдирдиреНрдп рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ, рдПрдХрд╛ рдирд┐рд░реАрдХреНрд╖рдгрд╛рдореБрд│реЗ, рдЖрдзреАрдЪ рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд░реЗрдХреЙрд░реНрдбрдЪреЗ рдкреВрд░реНрдг рдХреНрд▓реЛрди рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдХреЗрд▓реЗ рдЖрд╣реЗрдд.
рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдХрд╛рд▓рдХреНрд░рдорд╛рдиреБрд╕рд╛рд░ рдореЗрдЯреНрд░рд┐рдХрдЪреА рдореВрд▓реНрдпреЗ рдХреЙрдкреА рдкреНрд░рд╡рд╛рд╣ рд╡рд╛рдкрд░реВрди PostgreSQL рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реА рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдирдВрддрд░ рдЕрдЪрд╛рдирдХ рдЕрдкрдпрд╢ рдпреЗрддреЗ рдЖрдгрд┐ рдкреВрд░реНрдгрдкрдгреЗ рд╕рдорд╛рди рдбреЗрдЯрд╛рдЪрд╛ рдХрд╛рд╣реА рднрд╛рдЧ рдкреБрдиреНрд╣рд╛ рдпреЗрддреЛ.
рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХреНрд▓реЛрдирдЪреНрдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕рдкрд╛рд╕реВрди рдореБрдХреНрдд рдХрд╕реЗ рдХрд░рд╛рд╡реЗ?
рдЬреЗрд╡реНрд╣рд╛ рдкреАрдХреЗ рдорджрддрдиреАрд╕ рдирд╕рддреЛ
рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкрд╛ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ рдЕрд╢реА рдкрд░рд┐рд╕реНрдерд┐рддреА рдкреНрд░рдердо рд╕реНрдерд╛рдирд╛рд╡рд░ рдпреЗрдгреНрдпрд╛рдкрд╛рд╕реВрди рд░реЛрдЦрдгреЗ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдкреНрд░рд╛рдердорд┐рдХ рдХреА рд░реЛрд▓ рдХрд░рд╛. рдкрд░рдВрддреБ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдбреЗрдЯрд╛рдЪреА рдорд╛рддреНрд░рд╛ рд╡рд╛рдврд╡рд┐рд▓реНрдпрд╛рд╢рд┐рд╡рд╛рдп рд╣реЗ рдиреЗрд╣рдореАрдЪ рд╢рдХреНрдп рдирд╕рддреЗ.
рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЬрд░ рд╕реНрддреНрд░реЛрдд рдкреНрд░рдгрд╛рд▓реАрдЪреА рдЕрдЪреВрдХрддрд╛ рдбреЗрдЯрд╛рдмреЗрд╕рдордзреАрд▓ рдлреАрд▓реНрдбрдЪреНрдпрд╛ рдЕрдЪреВрдХрддреЗрдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЕрд╕реЗрд▓ рддрд░:
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 рд╕реНрдХреЕрдирд╕рд╛рдареА рдирд┐рд╡рдбрд▓реНрдпрд╛ рдЧреЗрд▓реНрдпрд╛ рдЖрдгрд┐ рдбреЗрдЯрд╛ рд╢реЛрдзрдгреНрдпрд╛рд╕рд╛рдареА рд╣рдЯрд╡рд╛ рдиреЛрдб рд╡рд╛рдкрд░рд▓рд╛ рдЧреЗрд▓рд╛. рдЯрд┐рдб рд╕реНрдХреЕрдирд╕рд╣ рдПрдХрд▓ рдкрд╛рд╕:
-> 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;
рдореНрд╣рдгреВрди, рдкрджреНрдзрдд рдпрд╢рд╕реНрд╡реАрд░рд┐рддреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░рддреЗ, рдкрд░рдВрддреБ рддреА рдХрд╛рд╣реА рд╕рд╛рд╡рдзрдЧрд┐рд░реАрдиреЗ рд╡рд╛рдкрд░рд▓реА рдкрд╛рд╣рд┐рдЬреЗ. рдХрд╛рд░рдг рд╣рдЯрд╡рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рд░реЗрдХреЙрд░реНрдбрд╕рд╛рдареА, рдЯрд┐рдб рд╕реНрдХреЕрдирдордзреНрдпреЗ рд╡рд╛рдЪрд▓реЗрд▓реЗ рдПрдХ рдбреЗрдЯрд╛ рдкреГрд╖реНрда рдЖрд╣реЗ рдЖрдгрд┐ рдПрдХ рд╣рдЯрд╡рд╛.
рд╕реНрддреНрд░реЛрдд: www.habr.com