PostgreSQL Antipatterns: berjast við hjörð af „dauðum“

Sérkenni innri aðferða PostgreSQL gerir það kleift að vera mjög hratt í sumum aðstæðum og „ekki mjög hratt“ í öðrum. Í dag munum við einblína á klassískt dæmi um átök milli þess hvernig DBMS virkar og þess sem verktaki gerir við það - UPDATE vs MVCC meginreglur.

Stutt saga frá frábær grein:

Þegar röð er breytt með UPDATE skipun eru tvær aðgerðir í raun gerðar: DELETE og INSERT. IN núverandi útgáfa af strengnum xmax er stillt jafnt og númer færslunnar sem framkvæmdi UPPfærsluna. Þá er það búið til ný útgáfa sama línan; xmin gildi þess fellur saman við xmax gildi fyrri útgáfu.

Nokkrum tíma eftir að þessari færslu er lokið, gamla eða nýja útgáfan, fer eftir COMMIT/ROOLBACK, verður viðurkennt "dauður" (dauðir tuples) þegar farið er framhjá VACUUM samkvæmt töflunni og hreinsaður.

PostgreSQL Antipatterns: berjast við hjörð af „dauðum“

En þetta mun ekki gerast strax, en vandamál með „dauða“ er hægt að eignast mjög fljótt - með endurteknum eða fjöldauppfærsla á skrám í stóru borði, og litlu síðar muntu lenda í sömu aðstæðum VACUUM mun ekki geta hjálpað.

#1: Mér finnst gaman að hreyfa það

Segjum að aðferðin þín sé að vinna á viðskiptarökfræði og skyndilega áttar hún sig á því að það væri nauðsynlegt að uppfæra X reitinn í einhverri skrá:

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

Síðan, þegar líður á framkvæmdina, kemur í ljós að Y reiturinn ætti einnig að vera uppfærður:

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

... og svo líka Z - af hverju að eyða tíma í smáræði?

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

Hversu margar útgáfur af þessari skrá höfum við núna í gagnagrunninum? Já, 4 stykki! Þar af er eitt viðeigandi og 3 verður að hreinsa upp eftir þig með [sjálfvirku]VACUUM.

Ekki gera þetta svona! Notaðu að uppfæra alla reiti í einni beiðni — næstum alltaf er hægt að breyta rökfræði aðferðarinnar á þessa leið:

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

#2: Notkun er aðgreind frá, Luke!

Svo þú vildir samt uppfæra margar, margar færslur í töflu (við notkun handrits eða breytir, til dæmis). Og eitthvað eins og þetta flýgur inn í handritið:

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

Beiðni á um það bil þessu formi kemur nokkuð oft og næstum alltaf um að fylla ekki út tóman nýjan reit heldur leiðrétta einhverjar villur í gögnunum. Á sama tíma, hún sjálf alls ekki er tekið tillit til réttmæti fyrirliggjandi gagna - en til einskis! Það er að segja að platan er endurskrifuð, jafnvel þótt hún innihaldi nákvæmlega það sem óskað var eftir - en hvers vegna? Við skulum laga það:

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

Margir eru ekki meðvitaðir um tilvist svo frábærs rekstraraðila, svo hér er svindlblað á IS DISTINCT FROM og aðrir rökrænir rekstraraðilar til að hjálpa:
PostgreSQL Antipatterns: berjast við hjörð af „dauðum“
... og smá um aðgerðir á flóknum ROW()-tjáningar:
PostgreSQL Antipatterns: berjast við hjörð af „dauðum“

#3: Ég kannast við elskuna mína með því að... loka

er verið að hleypa af stokkunum tvö eins samhliða ferli, sem hvert um sig reynir að merkja færsluna að hún sé „í vinnslu“:

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

Jafnvel þótt þessi ferli geri hlutina óháð hvert öðru, en innan sama auðkennis, verður annar viðskiptavinurinn „læstur“ á þessari beiðni þar til fyrstu færslunni er lokið.

Lausn #1: verkefnið er minnkað í það fyrra

Við skulum bara bæta því við aftur IS DISTINCT FROM:

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

Í þessu formi mun önnur beiðni einfaldlega ekki breyta neinu í gagnagrunninum, allt er nú þegar eins og það á að vera - þess vegna mun lokun ekki eiga sér stað. Næst vinnum við úr þeirri staðreynd að „finnum ekki“ færsluna í beittu reikniritinu.

Lausn #2: ráðgefandi læsingar

Stórt efni fyrir sérstaka grein, þar sem þú getur lesið um aðferðir við beitingu og "rake" af ráðleggingarblokkun.

Lausn #3: heimskir kallar

En þetta er einmitt það sem ætti að koma fyrir þig samtímis vinna með sömu skrá? Eða klúðraðirðu reikniritunum til að kalla viðskiptarökfræði viðskiptavinar megin, til dæmis? Og ef þú hugsar um það?..

Heimild: www.habr.com

Bæta við athugasemd