Ka lebaka la mosebetsi oa ka, ke tlameha ho sebetsana le maemo ha moqapi a ngola kopo mme a nahana "Motheo o bohlale, o khona ho sebetsana le ntho e 'ngoe le e' ngoe ka boeona!«
Maemong a mang (karolo e 'ngoe ka lebaka la ho hloka tsebo ea bokhoni ba database, karolo e 'ngoe ea ho ntlafatsa pele ho nako), mokhoa ona o lebisa ponahalong ea "Frankensteins".
Pele, ke tla fana ka mohlala oa kopo e joalo:
-- для каждой ключевой пары находим ассоциированные значения полей
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;
Ho lekola boleng ba kopo ka botlalo, ha re theheng sete ea data e sa reroang:
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);
Hoa etsahala hore ho bala data ho ile ha nka nako e ka tlase ho kotara ea nako phetho ea potso:
Ho e arola sekoto ka sengoathoana
Ha re shebisiseng kopo eo 'me re makale:
- Hobaneng ha LE RECURSIVE mona haeba ho se na li-CTE tse iphetang?
- Hobaneng ha lihlopha tsa min/max boleng ho CTE e arohaneng haeba li tlameletsoe ho sampole ea mantlha leha ho le joalo?
+ 25% ea nako - Ke hobane'ng ha u sebelisa 'KHETHA * HO TSOA' qetellong ho pheta CTE e fetileng?
+ 14% ea nako
Tabeng ena, re ne re le lehlohonolo haholo hore Hash Join e khethiloe bakeng sa ho hokahanya, eseng Nested Loop, hobane joale re ka be re sa fumane feela pase e le 'ngoe ea CTE Scan, empa 10K!
hanyane ka CTE ScanMona re lokela ho hopola seo CTE Scan e tšoana le Seq Scan - ke hore, ha ho indexing, empa ho batlisisa ka botlalo feela, ho ka hlokang 10K x 0.3ms = 3000ms bakeng sa lipotoloho ka cte_max kapa 1K x 1.5ms = 1500ms ha u roala ka cte_bind!
Ha e le hantle, u ne u batla ho fumana eng ka lebaka leo? E, hangata ena ke potso e hlahang kae-kae metsotsong ea 5 ea ho hlahloba lipotso tsa "mekato e meraro".
Re ne re batla ho hlahisa bakeng sa para e 'ngoe le e 'ngoe ea linotlolo tse ikhethang min/max ho tloha sehlopheng ka key_a.
Kahoo ha re e sebelisetseng sena
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);
Kaha data ea ho bala likhethong ka bobeli e nka hoo e ka bang 4-5ms, joale nako eohle ea rona e fumana phaello -32% - sena se ka sebopeho sa sona se hloekileng mojaro o tlositsoe ho base CPU, haeba kopo e joalo e etsoa hangata ho lekana.
Ka kakaretso, ha ua lokela ho qobella setsi ho "jara e pota-potileng, rola sekoere se le seng."
Source: www.habr.com