เดเดจเตเดฑเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดฐเตเดคเดฟ เดเดพเดฐเดฃเด, เดเดฐเต เดกเตเดตเดฒเดชเตเดชเตผ เดเดฐเต เด เดญเตเดฏเตผเดคเตเดฅเดจ เดเดดเตเดคเตเดเดฏเตเด เดเดฟเดจเตเดคเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ เดเดจเดฟเดเตเดเต เดธเดพเดนเดเดฐเตเดฏเดเตเดเตพ เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเตเดฃเตเดเดฟเดตเดฐเตเด "เด เดเดฟเดธเตเดฅเดพเดจเด เดฎเดฟเดเดเตเดเดคเดพเดฃเต, เด เดคเดฟเดจเต เดเดฒเตเดฒเดพเด เดธเตเดตเดฏเด เดเตเดเดพเดฐเตเดฏเด เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเตเด!ยซ
เดเดฟเดฒ เดธเดจเตเดฆเตผเดญเดเตเดเดณเดฟเตฝ (เดญเดพเดเดฟเดเดฎเดพเดฏเดฟ เดกเดพเดฑเตเดฑเดพเดฌเตเดธเดฟเดจเตเดฑเต เดเดดเดฟเดตเตเดเดณเตเดเตเดเตเดฑเดฟเดเตเดเตเดณเตเดณ เด
เดเตเดเดคเดฏเดฟเตฝ เดจเดฟเดจเตเดจเต, เดญเดพเดเดฟเดเดฎเดพเดฏเดฟ เด
เดเดพเดฒ เดเดชเตเดฑเตเดฑเดฟเดฎเตเดธเตเดทเดจเตเดเดณเดฟเตฝ เดจเดฟเดจเตเดจเต), เด เดธเดฎเตเดชเดจเด "เดซเตเดฐเดพเดเตเดเตเตปเดธเตเดฑเตเดฑเตเตปเดธเต" เดชเตเดฐเดคเตเดฏเดเตเดทเดชเตเดชเตเดเตเดจเตเดจเดคเดฟเดฒเตเดเตเดเต เดจเดฏเดฟเดเตเดเตเดจเตเดจเต.
เดเดฆเตเดฏเด, เด
เดคเตเดคเดฐเดฎเตเดฐเต เด
เดญเตเดฏเตผเดคเตเดฅเดจเดฏเตเดเต เดเดฐเต เดเดฆเดพเดนเดฐเดฃเด เดเดพเตป เดจเตฝเดเตเด:
-- ะดะปั ะบะฐะถะดะพะน ะบะปััะตะฒะพะน ะฟะฐัั ะฝะฐั
ะพะดะธะผ ะฐััะพัะธะธัะพะฒะฐะฝะฝัะต ะทะฝะฐัะตะฝะธั ะฟะพะปะตะน
WITH RECURSIVE cte_bind AS (
SELECT DISTINCT ON (key_a, key_b)
key_a a
, key_b b
, fld1 bind_fld1
, fld2 bind_fld2
FROM
tbl
)
-- ะฝะฐั
ะพะดะธะผ min/max ะทะฝะฐัะตะฝะธะน ะดะปั ะบะฐะถะดะพะณะพ ะฟะตัะฒะพะณะพ ะบะปััะฐ
, cte_max AS (
SELECT
a
, max(bind_fld1) bind_fld1
, min(bind_fld2) bind_fld2
FROM
cte_bind
GROUP BY
a
)
-- ัะฒัะทัะฒะฐะตะผ ะฟะพ ะฟะตัะฒะพะผั ะบะปััั ะบะปััะตะฒัะต ะฟะฐัั ะธ min/max-ะทะฝะฐัะตะฝะธั
, cte_a_bind AS (
SELECT
cte_bind.a
, cte_bind.b
, cte_max.bind_fld1
, cte_max.bind_fld2
FROM
cte_bind
INNER JOIN
cte_max
ON cte_max.a = cte_bind.a
)
SELECT * FROM cte_a_bind;
เดเดฐเต เด เดญเตเดฏเตผเดคเตเดฅเดจเดฏเตเดเต เดเตเดฃเดจเดฟเดฒเดตเดพเดฐเด เดเดฃเตเดฏเดฎเดพเดฏเดฟ เดตเดฟเดฒเดฏเดฟเดฐเตเดคเตเดคเตเดจเตเดจเดคเดฟเดจเต, เดจเดฎเตเดเตเดเต เดเดฟเดฒ เด เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดคเดฎเดพเดฏ เดกเดพเดฑเตเดฑ เดธเตเดฑเตเดฑเต เดธเตเดทเตเดเดฟเดเตเดเดพเด:
CREATE TABLE tbl AS
SELECT
(random() * 1000)::integer key_a
, (random() * 1000)::integer key_b
, (random() * 10000)::integer fld1
, (random() * 10000)::integer fld2
FROM
generate_series(1, 10000);
CREATE INDEX ON tbl(key_a, key_b);
เด เดคเต เดฎเดพเดฑเตเดจเตเดจเต เดกเดพเดฑเตเดฑ เดตเดพเดฏเดฟเดเตเดเดพเตป เดธเดฎเดฏเดคเตเดคเดฟเดจเตเดฑเต เดจเดพเดฒเดฟเดฒเตเดจเตเดจเดฟเตฝ เดคเดพเดดเต เดธเดฎเดฏเดฎเตเดเตเดคเตเดคเต เด เดจเตเดตเตเดทเดฃ เดจเดฟเตผเดตเตเดตเดนเดฃเด:
เด เดคเดฟเดจเต เดเดทเดฃเด เดเดทเดฃเดเตเดเดณเดพเดฏเดฟ เดตเตเตผเดชเตเดเตเดคเตเดคเตเดจเตเดจเต
เดจเดฎเตเดเตเดเต เด เดญเตเดฏเตผเดคเตเดฅเดจเดฏเต เดธเตเดเตเดทเตเดฎเดฎเดพเดฏเดฟ เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเดเดฏเตเด เด เดฎเตเดชเดฐเดชเตเดชเดฟเดเตเดเตเดเดฏเตเด เดเตเดฏเตเดฏเดพเด:
- เดฑเดฟเดเตเดเตเดดเตโเดธเตเดตเต CTE-เดเตพ เดเดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดจเตเดคเตเดเตเดฃเตเดเต เดเดตเดฟเดเต VITH RECURSIVE เดเดฏเดฟ?
- เดเดฑเดฟเดเดฟเดจเตฝ เดธเดพเดฎเตเดชเดฟเดณเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดเดฐเต เดชเตเดฐเดคเตเดฏเตเด CTE-เดฏเดฟเตฝ เดฎเดฟเดจเดฟ/เดฎเดพเดเตเดธเต เดฎเตเดฒเตเดฏเดเตเดเตพ เดเตเดฐเตเดชเตเดชเตเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดเดจเตเดคเตเดเตเดฃเตเดเต?
+ 25% เดธเดฎเดฏเด - เดฎเตเดฎเตเดชเดคเตเดคเต CTE เดเดตเตผเดคเตเดคเดฟเดเตเดเดพเตป เด
เดตเดธเดพเดจเด เดเดชเดพเดงเดฟเดเดณเดฟเดฒเตเดฒเดพเดคเตเดค 'SELECT * FROM' เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเดคเต เดเดจเตเดคเตเดเตเดฃเตเดเต?
+ 14% เดธเดฎเดฏเด
เด เดธเดพเดนเดเดฐเตเดฏเดคเตเดคเดฟเตฝ, เดจเตเดธเตเดฑเตเดฑเดกเต เดฒเตเดชเตเดชเดฒเตเดฒ, เดเดฃเดเตเดทเดจเดพเดฏเดฟ เดนเดพเดทเต เดเตเดฏเดฟเตป เดคเดฟเดฐเดเตเดเตเดเตเดคเตเดคเดคเต เดเดเตเดเตพ เดตเดณเดฐเต เดญเดพเดเตเดฏเดตเดพเดจเดพเดฏเดฟเดฐเตเดจเตเดจเต, เดเดพเดฐเดฃเด เด เดชเตเดชเตเตพ เดเดเตเดเตพเดเตเดเต เดเดฐเต CTE เดธเตเดเดพเตป เดชเดพเดธเต เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ, 10K เดฒเดญเดฟเดเตเดเตเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต!
CTE เดธเตเดเดพเดจเดฟเดจเตเดเตเดเตเดฑเดฟเดเตเดเต เดเตเดฑเดเตเดเตเดเดตเดฟเดเต เดจเดพเด เด
เดคเต เดเตผเดเตเดเดฃเด CTE เดธเตเดเดพเตป, Seq เดธเตเดเดพเตป เดชเตเดฒเตเดฏเดพเดฃเต - เด
เดคเดพเดฏเดคเต, เดเตปเดกเตเดเตโเดธเดฟเดเดเต เดเดฒเตเดฒ, เดชเดเตเดทเต เดชเตเตผเดฃเตเดฃเดฎเดพเดฏ เดคเดฟเดฐเดฏเตฝ เดฎเดพเดคเตเดฐเดฎเต เดเดตเดถเตเดฏเดฎเตเดณเตเดณเต 10K x 0.3ms = 3000 เดฎเดฟ cte_max เดตเดดเดฟเดฏเตเดณเตเดณ เดธเตเดเตเดเดฟเดณเตเดเตพเดเตเดเดพเดฏเดฟ เด
เดฅเดตเดพ 1K x 1.5ms = 1500 เดฎเดฟ cte_bind เดตเดดเดฟ เดฒเตเดชเตเดชเต เดเตเดฏเตเดฏเตเดฎเตเดชเตเตพ!
เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ, เดซเดฒเดฎเดพเดฏเดฟ เดจเดฟเดเตเดเตพเดเตเดเต เดเดจเตเดคเดพเดฃเต เดฒเดญเดฟเดเตเดเตเดฃเตเดเดคเต? เด
เดคเต, เดธเดพเดงเดพเดฐเดฃเดฏเดพเดฏเดฟ เดเดคเต "เดฎเตเดจเตเดจเต-เดจเดฟเดฒ" เด
เดจเตเดตเตเดทเดฃเดเตเดเตพ เดตเดฟเดถเดเดฒเดจเด เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดฑเต เด
เดเตเดเดพเด เดฎเดฟเดจเดฟเดฑเตเดฑเดฟเตฝ เดเดตเดฟเดเตเดฏเต เดตเดฐเตเดจเตเดจ เดเตเดฆเตเดฏเดฎเดพเดฃเต.
เดเดฐเต เด
เดฆเตเดตเดฟเดคเตเดฏ เดเต เดเตเดกเดฟเดเตเดเตเด เดเดเตเดเตเดชเตเดเตเดเต เดเตเดฏเตเดฏเดพเตป เดเดเตเดเตพ เดเดเตเดฐเดนเดฟเดเตเดเต เดเต_เด เดชเตเดฐเดเดพเดฐเด เดเตเดฐเตเดชเตเดชเดฟเตฝ เดจเดฟเดจเตเดจเต เดฎเดฟเดจเดฟเดฑเตเดฑเต/เดชเดฐเดฎเดพเดตเดงเดฟ.
เด
เดคเตเดเตเดฃเตเดเต เดจเดฎเตเดเตเดเต เดเดคเต เดเดชเดฏเตเดเดฟเดเตเดเดพเด
SELECT DISTINCT ON(key_a, key_b)
key_a a
, key_b b
, max(fld1) OVER(w) bind_fld1
, min(fld2) OVER(w) bind_fld2
FROM
tbl
WINDOW
w AS (PARTITION BY key_a);
เดฐเดฃเตเดเต เดเดชเตโเดทเดจเตเดเดณเดฟเดฒเตเดฏเตเด เดกเดพเดฑเตเดฑ เดตเดพเดฏเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดเดเดฆเตเดถเด 4-5 เดเดเดเดธเต เดเดเตเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเตฝ, เดเดเตเดเดณเตเดเต เดธเดฎเดฏเดฎเตเดฒเตเดฒเดพเด เดฒเดพเดญเดฟเดเตเดเตเด -32% - เดเดคเต เด เดคเดฟเดจเตเดฑเต เดถเตเดฆเตเดงเดฎเดพเดฏ เดฐเตเดชเดคเตเดคเดฟเดฒเดพเดฃเต เด เดเดฟเดธเตเดฅเดพเดจ เดธเดฟเดชเดฟเดฏเตเดตเดฟเตฝ เดจเดฟเดจเตเดจเต เดฒเตเดกเต เดจเตเดเตเดเด เดเตเดฏเตเดคเต, เด เดคเตเดคเดฐเดฎเตเดฐเต เด เดญเตเดฏเตผเดคเตเดฅเดจ เดชเดฒเดชเตเดชเตเดดเตเด เดจเดเดชเตเดชเดฟเดฒเดพเดเตเดเดฟเดฏเดพเตฝ เดฎเดคเดฟ.
เดชเตเดคเตเดตเต, "เดตเตเดคเตเดคเดพเดเตเดคเดฟเดฏเดฟเดฒเตเดณเตเดณเดคเต เดเตเดฃเตเดเตเดชเตเดเตเด, เดเดคเตเดฐเด เดเดฐเตเดเตเดเตเด" เดเดจเตเดจเต เดจเดฟเดเตเดเตพ เด
เดเดฟเดคเตเดคเดฑเดฏเต เดจเดฟเตผเดฌเดจเตเดงเดฟเดเตเดเดฐเตเดคเต.
เด
เดตเดฒเดเดฌเด: www.habr.com