Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Di derbarê ka me çawa pêdivî bû ku pirsa PostgreSQL xweşbîn bikin û çi ji her tiştî derket.
Çima hûn neçar bûn? Erê, ji ber ku 4 salên berê her tişt bi bêdengî, bi aramî, mîna saetekê dimeşiya.
Wek epîgraf.

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Li ser bingeha bûyerên rastîn.
Hemî nav hatine guhertin, tesadufî tesadufî ne.

Dema ku hûn encamek diyarkirî bi dest bixin, her gav balkêş e ku hûn bînin bîra xwe ka çi bû sedema destpêkê, li ku derê dest pê kir.

Ji ber vê yekê, tiştê ku di encamê de qewimî di gotarê de bi kurtî tê vegotin "Sentez wekî yek ji awayên çêtirkirina performansa PostgreSQL ye".

Dê belkî balkêş be ku meriv zincîra bûyerên berê ji nû ve biafirîne.
Dîrok dîroka destpêka rastîn xilas kir - 2018-09-10 18:02:48.
Di heman demê de, di çîrokê de daxwazek heye ku her tişt jê dest pê kir:
Daxwaza pirsgirêkêNEQANDIN
p."PARAMETER_ID" wekî parameter_id,
pd"PD_NAME" AS pd_name,
pd"CUSTOMER_PARTNUMBER" AS jimareya_mişterî,
w. "LRM" AS LRM,
w. "LOTID" AS lotid,
w."RTD_VALUE" WEKE RTD_nirx,
w."LOWER_SPEC_LIMIT" AS ASÎNÊ_Spec_nizimtir,
w.“UPPER_SPEC_LIMIT” AS ASÎNÊ_spec_jorîn,
p"TYPE_CALCUL" AS type_calcul,
s"SPENT_NAME" AS navê xerckirî,
s."SPENT_DATE" AS date_ xerckirin,
jêbirin(sal ji "SPENT_DATE") AS sal,
derxe (meha ji "SPENT_DATE") wekî meh,
s"REPORT_NAME" AS report_name,
p"STPM_NAME" AS stpm_name,
rûp.“CUSTOMERPARAM_NAME” AS navê xerîdarparam_name
JI wdata w,
xerc kirin s,
pmtr p,
spent_pd sp,
PD PD
WHERE s."SPENT_ID" = w."SPENT_ID"
Û p."PARAMETER_ID" = w"PARAMETER_ID"
Û s."SPENT_ID" = sp."SPENT_ID"
Û pd."PD_ID" = sp."PD_ID"
AND s."SPENT_DATE" >= '2018-07-01' Û s."SPENT_DATE" <= '2018-09-30'
û s.“SPENT_DATE” = (HILBIJARTIN MAX(s2.“SPENT_DATE”)
JI s2 derbas kir,
wdata w2
WHERE s2."SPENT_ID" = w2."SPENT_ID"
Û w2.“LRM” = w.“LRM”);


Danasîna pirsgirêkê bi pêşbînî standard e - "Her tişt xirab e. Ji min re bêje pirsgirêk çi ye.”
Di cih de anekdotek ji dema ajokarên 3 û nîv inç hat bîra min:

Lamer tê hakerê.
-Tiştek ji min re nayê, ji min re bêje pirsgirêk li ku ye.
-Di DNA de...

Lê bê guman, ev ne awayê çareserkirina bûyerên performansê ye. "Dibe ku ew me fêm nekin" (Bi). Pêdivî ye ku em wê fêhm bikin.
Baş e, em bikolin. Dibe ku di encamê de tiştek kom bibe.

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Lêkolîn dest pê kir

Ji ber vê yekê, tiştê ku di cih de bi çavê rût tê dîtin, bêyî ku serî li RÊŞANDINÊ jî bide.
1) JOIN nayên bikaranîn. Ev xirab e, nemaze heke hejmara girêdan ji yekê zêdetir be.
2) Lê ya ku hîn xirabtir e, bi hev ve girêdayî ye, ji bilî vê, bi kombûnê. Ev pir xerab e.
Bê guman ev xirab e. Lê ev tenê ji aliyekî ve ye. Ji aliyê din ve, ev pir baş e, ji ber ku pirsgirêk bi eşkere çareseriyek û daxwazek heye ku dikare çêtir bibe.
Neçe ba felekê (C).
Plana pirsê ne ew çend tevlihev e, lê ew pir diyarker e:
Plana PêkanînêTê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Ya herî balkêş û bikêr, wekî her car, di destpêkê û dawiyê de ye.
Çêlika Nested (lêçûn = 935.84..479763226.18 rêz = 3322 firehî = 135) (dema rastîn = 31.536..8220420.295 rêz = 8111656 xelek = 1)
Dema plankirinê: 3.807 ms
Dema darvekirinê: 8222351.640 ms
Dema qedandinê ji 2 saetan zêdetir e.

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Hîpotezên derewîn ku dem girt

Hîpoteza 1 - Optimîzator xeletiyek dike û plana xelet ava dike.

Ji bo dîtina plana darvekirinê, em ê malperê bikar bînin https://explain.depesz.com/. Lêbelê, malperê tiştek balkêş an kêrhatî nîşan neda. Di nihêrîna yekem û duyemîn de, tiştek ku bi rastî dikare alîkariyê bike tune. Ma gengaz e ku Skaniya Tevahî hindik be. Berdewam bike.

Hîpoteza 2-Bandora li ser bingehê ji hêla otovacuumê ve, pêdivî ye ku hûn ji frensan xilas bibin.

Lê şeytanên otovacuumê baş tevdigerin, pêvajoyên dirêj-dirêj tune. No load cidî. Divê em li tiştekî din bigerin.

Hîpoteza 3 - Amar kevnar in, divê her tişt ji nû ve were hesibandin

Dîsa, ne ew. Îstatîstîkên nûjen in. Ku, ji ber nebûna pirsgirêkên bi otovacuumê re, ne ecêb e.

Ka em dest bi xweşbîniyê bikin

Tabloya sereke 'wdata' bê guman ne piçûk e, hema hema 3 mîlyon tomar e.
Û ev tabloya ku Full Scan dişopîne ye.

Hash Cond: ((w"SPENT_ID" = s."SPENT_ID") Û ((Subplan 1) = s."SPENT_DATE"))
-> Seq Scan li ser wdata w (lêçûn = 0.00..574151.49 rêz = 26886249 firehî = 46) (dema rastîn = 0.005..8153.565 rêz = 26873950 xelek = 1)
Em tiştê standard dikin: "Werin, werin em navnîşek çêbikin û her tişt dê bifire."
Li ser zeviya "SPENT_ID" indexek çêkir
Di encamê da:
Plana darvekirina pirsê bi karanîna indexêTê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Baş e, ew alîkarî kir?
Bû: 8 222 351.640 ms (piçek zêdetir ji 2 saetan)
Bû: 6 985 431.575 ms (hema 2 saetan)
Bi gelemperî, heman sêv, dîtina alî.
Em klasîkan bînin bîra xwe:
“Ma we heman yek heye, lê bê bask? Dê bigerin."

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Di prensîbê de, ev dikare wekî encamek baş, baş, ne baş, lê qebûl kirin. Bi kêmanî, raporek mezin ji xerîdar re peyda bikin ku diyar dike ka çiqas hatiye kirin û çima ya ku hate kirin baş bû.
Lê dîsa jî, biryara dawî hîn dûr e. Pir dur.

Û naha ya herî balkêş - em xweşbîniyê didomînin, em ê daxwazê ​​bişopînin

Gav Yek - JOIN bikar bînin

Daxwaza ji nû ve hatî nivîsandin niha bi vî rengî xuya dike (bi kêmanî xweşiktir e):
Pirs bi bikaranîna JOINNEQANDIN
p."PARAMETER_ID" wekî parameter_id,
pd"PD_NAME" AS pd_name,
pd"CUSTOMER_PARTNUMBER" AS jimareya_mişterî,
w. "LRM" AS LRM,
w. "LOTID" AS lotid,
w."RTD_VALUE" WEKE RTD_nirx,
w."LOWER_SPEC_LIMIT" AS ASÎNÊ_Spec_nizimtir,
w.“UPPER_SPEC_LIMIT” AS ASÎNÊ_spec_jorîn,
p"TYPE_CALCUL" AS type_calcul,
s"SPENT_NAME" AS navê xerckirî,
s."SPENT_DATE" AS date_ xerckirin,
jêbirin(sal ji "SPENT_DATE") AS sal,
derxe (meha ji "SPENT_DATE") wekî meh,
s"REPORT_NAME" AS report_name,
p"STPM_NAME" AS stpm_name,
rûp.“CUSTOMERPARAM_NAME” AS navê xerîdarparam_name
JI wdata w JOIN INNER LI ser w xerc kir.“SPENT_ID”=s.”“SPENT_ID”
JOIN INNER pmtr p ON rûp.“PARAMETER_ID” = w.“PARAMETER_ID”
JOIN INNER spent_pd sp ON s.“SPENT_ID” = sp.“SPENT_ID”
JI INNER JOIN pd pd ON pd.“PD_ID” = sp.“PD_ID”
KO
s."SPENT_DATE" >= '2018-07-01' Û s."SPENT_DATE" <= '2018-09-30'Û
s."SPENT_DATE" = (HILBIJARTIN MEXT(s2."SPENT_DATE")
JI wdata w2 INNER JOIN s2 LI W2 xerc kir.“SPENT_ID”=s2.“SPENT_ID”
TEVLÊBÛNA HUNDIR wdata w
ON w2.“LRM” = w.“LRM” );
Dema plankirinê: 2.486 ms
Dema darvekirinê: 1223680.326 ms

Ji ber vê yekê, encama yekem.
Bû: 6 ms (hema 985 saetan).
Bû: 1 223 680.326 ms (zêdeyî 20 hûrdeman).
Encamek baş. Di prensîbê de, dîsa, em dikarin li wir rawestin. Lê ew qas nebalkêş e, hûn nekarin rawestin.
BO

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Gav du - ji binpirsîna têkildar xilas bibin

Nivîsara daxwaznameyê guhert:
Bêyî binavkirinên têkildarNEQANDIN
p."PARAMETER_ID" wekî parameter_id,
pd"PD_NAME" AS pd_name,
pd"CUSTOMER_PARTNUMBER" AS jimareya_mişterî,
w. "LRM" AS LRM,
w. "LOTID" AS lotid,
w."RTD_VALUE" WEKE RTD_nirx,
w."LOWER_SPEC_LIMIT" AS ASÎNÊ_Spec_nizimtir,
w.“UPPER_SPEC_LIMIT” AS ASÎNÊ_spec_jorîn,
p"TYPE_CALCUL" AS type_calcul,
s"SPENT_NAME" AS navê xerckirî,
s."SPENT_DATE" AS date_ xerckirin,
jêbirin(sal ji "SPENT_DATE") AS sal,
derxe (meha ji "SPENT_DATE") wekî meh,
s"REPORT_NAME" AS report_name,
p"STPM_NAME" AS stpm_name,
rûp.“CUSTOMERPARAM_NAME” AS navê xerîdarparam_name
JI wdata w JOIN INNER LI SER s xerc kirin.“SPENT_ID” = w.“SPENT_ID”
JOIN INNER pmtr p ON rûp.“PARAMETER_ID” = w.“PARAMETER_ID”
JOIN INNER spent_pd sp ON s.“SPENT_ID” = sp.“SPENT_ID”
JI INNER JOIN pd pd ON pd.“PD_ID” = sp.“PD_ID”
JI INNER JOIN (HILBIJARTIN w2.“LRM”, MAX(s2.“SPENT_DATE”)
JI xerckirin s2. INNER JOIN wdata w2 ON s2.“SPENT_ID” = w2.“SPENT_ID”
GROUP BY w2. "LRM"
) md li ser w."LRM" = md."LRM"
KO
s."SPENT_DATE" >= '2018-07-01' Û s."SPENT_DATE" <= '2018-09-30';
Dema plankirinê: 2.291 ms
Dema darvekirinê: 165021.870 ms

Bû: 1 223 680.326 ms (zêdeyî 20 hûrdeman).
Bû: 165 021.870 ms (zêdeyî 2 hûrdeman).
Ev jixwe pir baş e.
Lêbelê, wekî ku Brîtanî dibêjin "Lê belê, her tim lê heye" Encamek pir baş divê bixweber gumanan derxe. Li vir tiştek xelet e.

Hîpoteza li ser rastkirina pirsê ku ji jêrpirsiya têkildar xilas bibe rast e. Lê ji bo ku encama dawî rast be, hûn hewce ne ku wê hinekî bişoxilînin.
Wekî encamek, yekem encama navîn:
Lêpirsîna guherî bêyî binavbera têkildarNEQANDIN
p."PARAMETER_ID" wekî parameter_id,
pd"PD_NAME" AS pd_name,
pd"CUSTOMER_PARTNUMBER" AS jimareya_mişterî,
w. "LRM" AS LRM,
w. "LOTID" AS lotid,
w."RTD_VALUE" WEKE RTD_nirx,
w."LOWER_SPEC_LIMIT" AS ASÎNÊ_Spec_nizimtir,
w.“UPPER_SPEC_LIMIT” AS ASÎNÊ_spec_jorîn,
p"TYPE_CALCUL" AS type_calcul,
s"SPENT_NAME" AS navê xerckirî,
s."SPENT_DATE" AS date_ xerckirin,
jêgirtin (sala ji s.“SPENT_DATE”) AS sal,
derxe (meha ji s.“SPENT_DATE”) wekî meh,
s"REPORT_NAME" AS report_name,
p"STPM_NAME" AS stpm_name,
rûp.“CUSTOMERPARAM_NAME” AS navê xerîdarparam_name
JI wdata w JOIN INNER LI SER s xerc kirin.“SPENT_ID” = w.“SPENT_ID”
JOIN INNER pmtr p ON rûp.“PARAMETER_ID” = w.“PARAMETER_ID”
JOIN INNER spent_pd sp ON s.“SPENT_ID” = sp.“SPENT_ID”
JI INNER JOIN pd pd ON pd.“PD_ID” = sp.“PD_ID”
INNER JOIN (HILBIJÊRE w2."LRM", MAX(s2."SPENT_DATE") WEKE "SPENT_DATE"
JI xerckirin s2. INNER JOIN wdata w2 ON s2.“SPENT_ID” = w2.“SPENT_ID”
GROUP BY w2. "LRM"
) md ON md."SPENT_DATE" = s."SPENT_DATE" Û md."LRM" = w."LRM"
KO
s."SPENT_DATE" >= '2018-07-01' Û s."SPENT_DATE" <= '2018-09-30';
Dema plankirinê: 3.192 ms
Dema darvekirinê: 208014.134 ms

Ji ber vê yekê, ya ku em bi dawî dibin yekem encama pejirandî ye, ku ne şerm e ku meriv ji xerîdar re nîşan bide:
Bi dest pê kir: 8 222 351.640 ms (ji 2 saetan zêdetir)
Me bi dest xist: 1 ms (ji 223 hûrdeman piçek zêdetir).
Encam (navber): 208 014.134 ms (ji 3 hûrdeman zêdetir).

Encama hêja.

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

Encam

Em dikaribûn li wir rawestiyana.
LEBÊ…
Xwarin bi xwarinê tê. Yê ku bimeşe dê serdestiya rê bike. Her encamek navîn e. Rawestiya û mir. hwd.
Werin em optimîzasyonê bidomînin.
Fikra mezin. Bi taybetî ji ber ku xerîdar jî hişê xwe nedikir. Û ji bo wê jî bi hêz.

Ji ber vê yekê, wextê ji nû ve sêwirana databasê ye. Struktura pirsê bixwe êdî nikare xweşbîn bibe (her çend, wekî ku paşê derket holê, vebijarkek heye ku pê ewle bibe ku her tişt bi rastî têk diçe). Lê destpêkirina xweşbînkirin û pêşvebirina sêwirana databasê jixwe ramanek pir hêvîdar e. Û ya herî girîng balkêş. Dîsa ciwaniya xwe bi bîr bînin. Ez tavilê nebûm DBA, ez wekî bernamenûs mezin bûm (BASIC, assembler, C, du-plus C, Oracle, plsql). Mijarek balkêş, bê guman, ji bo bîranînek cûda ;-).
Lêbelê, bila em bala xwe nedin.

Û vî awayî,

Tê bîra te ku çawa hemû dest pê kir. Her tişt ji bo cara yekem û dîsa bû

An jî dibe ku dabeşkirin dê alîkariya me bike?
Spoiler - "Erê, ew alîkarî kir, di nav de di xweşbînkirina performansê de."

Lê ew çîrokek bi tevahî cûda ye ...

Ez bêtir ji te hez dikim…

Source: www.habr.com

Add a comment