Chifukwa cha ntchito yanga, ndiyenera kuthana ndi zochitika zomwe wopanga alemba pempho ndikuganiza "Maziko ndi anzeru, amatha kuthana ndi chilichonse chokha!Β«
Nthawi zina (mwina chifukwa cha kusadziwa luso la Nawonso achichepere, mwina kuchokera kukhathamiritsa msanga), njira imeneyi kumabweretsa maonekedwe a "Frankensteins".
Choyamba, ndipereka chitsanzo cha pempho lotere:
-- Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠΉ ΠΏΠ°ΡΡ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ Π°ΡΡΠΎΡΠΈΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ»Π΅ΠΉ
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;
Kuti tiwone bwinobwino momwe pempho likuyendera, tiyeni tipange seti ya data yokhazikika:
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);
Zikukhalira kuti kuwerenga deta anatenga zosakwana kotala la nthawi kufunsa mafunso:
Kuchigawaniza chidutswa ndi chidutswa
Tiyeni tiwone bwinobwino pempholo ndikudabwa:
- Chifukwa chiyani WITH RECURSIVE apa ngati palibe ma CTE obwereza?
- Chifukwa chiyani magulu a min/max mu CTE yosiyana ngati amangiriridwa ku zitsanzo zoyambirira?
+ 25% nthawi - Chifukwa chiyani mugwiritse ntchito 'SAKHANI * KUCHOKERA' kumapeto kuti mubwereze CTE yam'mbuyo?
+ 14% nthawi
Pankhaniyi, tinali ndi mwayi kwambiri kuti Hash Join adasankhidwa kuti alumikizane, osati Nested Loop, chifukwa ndiye tikadalandira osati CTE Scan imodzi yokha, koma 10K!
pang'ono za CTE ScanApa tiyenera kukumbukira CTE Scan ndi yofanana ndi Seq Scan - ndiko kuti, palibe indexing, koma kufufuza kwathunthu, komwe kungafune 10K x 0.3ms = 3000ms zozungulira ndi cte_max kapena 1K x 1.5ms = 1500ms pozungulira ndi cte_bind!
Kwenikweni, kodi mumafuna mutapeza chiyani? Inde, nthawi zambiri ili ndi funso lomwe limabwera penapake mu mphindi ya 5 pofufuza mafunso a "nsanjika zitatu".
Tinkafuna kutulutsa makiyi aliwonse apadera min/kuchuluka kuchokera pagulu ndi key_a.
Ndiye tiyeni tigwiritse ntchito izi
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);
Popeza kuwerenga zambiri pazosankha ziwirizi kumatenga pafupifupi 4-5ms, ndiye kuti nthawi yathu yonse imapindula -32% - izi ziri mu mawonekedwe ake oyera katundu wachotsedwa ku base CPU, ngati pempho loterolo likuchitidwa nthawi zambiri mokwanira.
Nthawi zambiri, simuyenera kukakamiza maziko "kunyamula chozungulira, gudubuza lalikulu."
Source: www.habr.com