Antipatterns za PostgreSQL: kupigana na kundi la "wafu"

Upekee wa mifumo ya ndani ya PostgreSQL inaruhusu iwe haraka sana katika hali zingine na "sio haraka sana" kwa zingine. Leo tutazingatia mfano wa kawaida wa mzozo kati ya jinsi DBMS inavyofanya kazi na kile msanidi hufanya nayo - UPDATE dhidi ya kanuni za MVCC.

Hadithi fupi kutoka makala kubwa:

Wakati safu mlalo inarekebishwa na amri ya UPDATE, shughuli mbili zinafanywa: DELETE na INSERT. KATIKA toleo la sasa la kamba xmax imewekwa sawa na idadi ya shughuli iliyofanya USASISHAJI. Kisha inaundwa toleo jipya mstari huo huo; thamani yake ya xmin inalingana na thamani ya xmax ya toleo la awali.

Muda fulani baada ya shughuli hii kukamilika, toleo la zamani au jipya, kulingana na COMMIT/ROOLBACK, itatambuliwa "wafu" (wafuasi waliokufa) ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π΅ VACUUM kulingana na meza na kusafishwa.

Antipatterns za PostgreSQL: kupigana na kundi la "wafu"

Lakini hii haitatokea mara moja, lakini shida na "wafu" zinaweza kupatikana haraka sana - kwa kurudiwa au sasisho kubwa la kumbukumbu katika meza kubwa, na baadaye kidogo utakutana na hali sawa VACUUM haitaweza kusaidia.

#1: Ninapenda Kuihamisha

Wacha tuseme njia yako inafanya kazi kwa mantiki ya biashara, na ghafla inagundua kuwa itakuwa muhimu kusasisha uga wa X katika rekodi fulani:

UPDATE tbl SET X = <newX> WHERE pk = $1;

Halafu, wakati utekelezaji unavyoendelea, inabadilika kuwa uwanja wa Y unapaswa kusasishwa pia:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... na kisha pia Z - kwa nini upoteze wakati kwenye vitapeli?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Je, sasa tuna matoleo mangapi ya rekodi hii kwenye hifadhidata? Ndio, vipande 4! Kati ya hizi, moja inafaa, na 3 italazimika kusafishwa baada yako na [otomatiki] VACUUM.

Usifanye hivi! Tumia kusasisha sehemu zote katika ombi moja - karibu kila wakati mantiki ya njia inaweza kubadilishwa kama hii:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

#2: Matumizi NI TOFAUTI NA, Luka!

Kwa hivyo, bado ulitaka sasisha rekodi nyingi, nyingi kwenye jedwali (wakati wa matumizi ya hati au kubadilisha fedha, kwa mfano). Na kitu kama hiki kinaruka kwenye hati:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

Ombi katika takriban fomu hii hutokea mara nyingi na karibu kila mara si kujaza sehemu mpya tupu, lakini kurekebisha baadhi ya makosa katika data. Wakati huo huo, yeye mwenyewe usahihi wa data zilizopo hauzingatiwi kabisa - lakini bure! Hiyo ni, rekodi inaandikwa upya, hata ikiwa ilikuwa na kile kilichotakiwa - lakini kwa nini? Hebu turekebishe:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Watu wengi hawajui juu ya uwepo wa mwendeshaji mzuri kama huyo, kwa hivyo hapa kuna karatasi ya kudanganya IS DISTINCT FROM na waendeshaji wengine wenye mantiki kusaidia:
Antipatterns za PostgreSQL: kupigana na kundi la "wafu"
... na kidogo juu ya shughuli kwenye tata ROW()-maneno:
Antipatterns za PostgreSQL: kupigana na kundi la "wafu"

#3: Namtambua mpenzi wangu kwa... kumzuia

zinazinduliwa michakato miwili inayofanana, ambayo kila moja inajaribu kutia alama kwenye ingizo kwamba "inaendelea":

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Hata kama taratibu hizi zitafanya mambo bila kujali, lakini ndani ya kitambulisho sawa, mteja wa pili "atafungwa" kwa ombi hili hadi muamala wa kwanza ukamilike.

Suluhisho # 1: kazi imepunguzwa hadi ya awali

Wacha tuiongeze tena IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

Katika fomu hii, ombi la pili halitabadilisha chochote kwenye hifadhidata, kila kitu tayari ni kama inavyopaswa kuwa - kwa hivyo, kuzuia haitatokea. Ifuatayo, tunashughulikia ukweli wa "kutopata" rekodi katika algorithm iliyotumika.

Suluhisho # 2: kufuli za ushauri

Mada kubwa kwa makala tofauti, ambayo unaweza kusoma kuhusu njia za maombi na "rake" ya kuzuia mapendekezo.

Suluhisho # 3: simu za kijinga

Lakini hii ndio hasa inapaswa kutokea kwako kazi ya wakati mmoja na rekodi sawa? Au umevuruga kanuni za kuita mantiki ya biashara kwenye upande wa mteja, kwa mfano? Na ikiwa unafikiria juu yake? ..

Chanzo: mapenzi.com

Kuongeza maoni