Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Go leor atá ag baint úsáide as cheana féin mínigh.tensor.ru - seans nach bhfuil ár seirbhís léirshamhlaithe plean PostgreSQL ar an eolas faoi cheann dá sárchumhachtaí - ag casadh píosa de loga an fhreastalaí atá deacair le léamh...

Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil
... isteach i gceist atá deartha go hálainn le leideanna comhthéacsúla do na nóid phlean comhfhreagracha:

Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil
Sa tras-scríbhinn seo den dara cuid dá tuarascáil ag PGConf.Russia 2020 Inseoidh mé duit conas a d'éirigh linn é seo a dhéanamh.

Tá athscríbhinn na chéad pháirte, atá tiomnaithe do ghnáthfhadhbanna feidhmíochta fiosrúcháin agus a réitigh, le fáil san alt "Oidis le haghaidh ceisteanna SQL tinn".



Ar dtús, cuirimis tús le dathú - agus ní dhéanfaimid dath an phlean a thuilleadh, tá daite againn cheana féin, tá sé álainn agus intuigthe againn cheana féin, ach iarratas.

Chonacthas dúinn go bhfuil cuma an-ghránna ar an iarratas a bhaintear as an loga agus dá bhrí sin nach bhfuil sé ró-fhormáideach ar a leithéid de “bhileog” neamhfhormáidithe.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Go háirithe nuair a "gliú" forbróirí an comhlacht ar an iarratas sa chód (tá sé seo, ar ndóigh, ar antipattern, ach a tharlaíonn sé) i líne amháin. Uafásach!

Déanaimis é seo a tharraingt ar bhealach níos áille.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Agus más féidir linn é seo a tharraingt go hálainn, is é sin, corp na hiarrata a dhíchóimeáil agus a chur ar ais le chéile, ansin is féidir linn leid a “cheangail” le gach ábhar den iarraidh seo - rud a tharla ag an bpointe comhfhreagrach sa phlean.

Ceist chomhréire crann

Chun seo a dhéanamh, ní mór an t-iarratas a pharsáil ar dtús.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Toisc go bhfuil againn ritheann croí an chórais ar NodeJS, ansin rinneamar modúl dó, is féidir leat é a fháil ar GitHub. Déanta na fírinne, is “ceangail” iad seo go dtí na hinmheánacha sa pharsálaí PostgreSQL féin. Is é sin le rá nach bhfuil sa ghramadach ach dénártha a thiomsú agus ceangailtear í ó NodeJS. Thógamar modúil daoine eile mar bhunús - níl aon rún mór anseo.

Cothaímid corp an iarratais mar ionchur dár bhfeidhm - ag an aschur faighimid crann comhréire parsáilte i bhfoirm réad JSON.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Anois is féidir linn rith tríd an gcrann seo sa treo eile agus iarratas a chur le chéile leis na fleasc, dathú agus formáidiú a theastaíonn uainn. Níl, níl sé seo saincheaptha, ach ba chosúil dúinn go mbeadh sé seo áisiúil.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Ceist mapála agus nóid phlean

Anois, féachaimis conas is féidir linn an plean a ndearnamar anailís air sa chéad chéim agus an cheist a ndearnamar anailís air sa dara ceann a chur le chéile.

Glacaimis sampla simplí - tá ceist againn a ghineann CTE agus a léann uaidh faoi dhó. Gineann sé a leithéid de phlean.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

CTE

Má fhéachann tú air go cúramach, suas go dtí leagan 12 (nó ag tosú uaidh leis an eochairfhocal MATERIALIZED) foirmiú Is bac iomlán é CTE don phleanálaí.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Ciallaíonn sé seo má fheiceann muid glúin CTE áit éigin san iarraidh agus nód áit éigin sa phlean CTE, ansin na nóid cinnte "troid" lena chéile, is féidir linn a chur le chéile láithreach iad.

Fadhb le réiltín: Is féidir CTEanna a neadú.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil
Tá cinn an-lag neadaithe, agus fiú cinn den ainm céanna. Mar shampla, is féidir leat taobh istigh CTE A a dhéanamh CTE X, agus ar an leibhéal céanna taobh istigh CTE B déan arís é CTE X:

WITH A AS (
  WITH X AS (...)
  SELECT ...
)
, B AS (
  WITH X AS (...)
  SELECT ...
)
...

Agus tú ag déanamh comparáide, caithfidh tú é seo a thuiscint. Tá sé an-deacair é seo a thuiscint “le do shúile” - fiú an plean a fheiceáil, fiú corp an iarratais a fheiceáil. Má tá do ghlúin CTE casta, neadaithe, agus go bhfuil na hiarratais mór, tá sé go hiomlán gan aithne.

AONTAIS

Má tá eochairfhocal againn sa cheist UNION [ALL] (oibreoir dhá shampla a cheangail), ansin sa phlean comhfhreagraíonn sé do cheachtar nód Append, nó roinnt Recursive Union.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

An rud atá "thuas" thuas UNION - is é seo an chéad sliocht ár nód, atá "thíos" - an dara. Má tríd UNION ní mór dúinn roinnt bloic "glued" ag an am céanna, mar sin Append- ní bheidh ach nód amháin ann fós, ach ní bheidh dhá cheann aige, ach go leor leanaí - san ord a théann siad, faoi seach:

  (...) -- #1
UNION ALL
  (...) -- #2
UNION ALL
  (...) -- #3

Append
  -> ... #1
  -> ... #2
  -> ... #3

Fadhb le réiltín: giniúint samplála athfhillteach laistigh (WITH RECURSIVE) is féidir freisin a bheith níos mó ná aon UNION. Ach ní bhíonn ach an bloc deiridh tar éis an ceann deiridh athchúrsach i gcónaí UNION. Tá gach rud thuas amháin, ach difriúil UNION:

WITH RECURSIVE T AS(
  (...) -- #1
UNION ALL
  (...) -- #2, тут кончается генерация стартового состояния рекурсии
UNION ALL
  (...) -- #3, только этот блок рекурсивный и может содержать обращение к T
)
...

Ní mór duit a bheith in ann samplaí den sórt sin a “mhaolú”. Sa sampla seo feicimid é sin UNION-bhí 3 mhír inár n-iarratas. Dá réir sin, ceann amháin UNION соответствует Append- nód, agus go dtí an taobh eile - Recursive Union.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Léigh-scríobh sonraí

Tá gach rud leagtha amach, anois tá a fhios againn cén píosa den iarratas a fhreagraíonn do cén píosa den phlean. Agus sna píosaí seo is féidir linn na réada sin atá “inléite” a aimsiú go héasca agus go nádúrtha.

Ó thaobh ceisteanna de, níl a fhios againn cé acu tábla nó CTE atá i gceist, ach ainmnítear iad leis an nód céanna RangeVar. Agus i dtéarmaí “inléiteacht”, is sraith measartha teoranta nod é seo freisin:

  • Seq Scan on [tbl]
  • Bitmap Heap Scan on [tbl]
  • Index [Only] Scan [Backward] using [idx] on [tbl]
  • CTE Scan on [cte]
  • Insert/Update/Delete on [tbl]

Tá struchtúr an phlean agus an cheist ar eolas againn, tá comhfhreagras na mbloc ar eolas againn, tá ainmneacha na réad ar eolas againn - déanaimid comparáid duine le duine.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Arís tasc "le réiltín". Glacaimid an t-iarratas, déanaimid é, níl aon ailiasanna againn - ní dhéanaimid é a léamh faoi dhó ón CTE céanna.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Breathnaímid ar an bplean - cad é an fhadhb? Cén fáth go raibh ailias againn? Níor ordaigh muid é. Cá bhfaigheann sé a leithéid de “uimhir”?

Cuireann PostgreSQL é féin leis. Ní mór duit ach é sin a thuiscint ach ailias den sórt sin dúinne, chun críocha comparáide leis an bplean, ní dhéanann sé aon chiall, cuirtear go simplí leis anseo. A ligean ar aird a thabhairt dó.

An dara tasc "le réiltín": má tá muid ag léamh ó tábla deighilte, ansin gheobhaidh muid nód AppendMerge Append, a bheidh comhdhéanta de líon mór “leanaí”, agus beidh gach ceann acu ar bhealach éigin Scan'om ón rannán tábla: Seq Scan, Bitmap Heap ScanIndex Scan. Ach, ar aon nós, ní ceisteanna casta a bheidh sna “leanaí” seo - seo conas is féidir idirdhealú a dhéanamh idir na nóid seo Append ag UNION.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Tuigimid freisin snaidhmeanna den sórt sin, bailímid iad “i gcarn amháin” agus abair: “tá gach rud a léann tú ó megatable anseo agus síos an crann".

"Simplí" sonraí a fháil nóid

Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Values Scan fhreagraíonn sa phlean VALUES san iarratas.

Result is iarratas gan FROM mhaith SELECT 1. Nó nuair a bhíonn léiriú bréagach d’aon ghnó agat i WHERE-block (ansin tá an tréith le feiceáil One-Time Filter):

EXPLAIN ANALYZE
SELECT * FROM pg_class WHERE FALSE; -- или 0 = 1

Result  (cost=0.00..0.00 rows=0 width=230) (actual time=0.000..0.000 rows=0 loops=1)
  One-Time Filter: false

Function Scan “léarscáil” chuig na SRFanna den ainm céanna.

Ach le fiosruithe neadaithe tá gach rud níos casta - ar an drochuair, ní bhíonn siad ag casadh i gcónaí InitPlan/SubPlan. Uaireanta téann siad isteach ... Join... Anti Join, go háirithe nuair a scríobhann tú rud éigin mar WHERE NOT EXISTS .... Agus anseo ní féidir iad a chomhcheangal i gcónaí - i dtéacs an phlean níl aon oibreoirí a fhreagraíonn do nóid an phlean.

Arís tasc "le réiltín": cuid VALUES san iarratas. Sa chás seo agus sa phlean gheobhaidh tú roinnt nóid Values Scan.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Cabhróidh iarmhíreanna “Uimhrithe” chun iad a idirdhealú óna chéile - cuirtear leis go beacht iad san ord ina bhfaightear na cinn chomhfhreagracha VALUES-bloic feadh an iarratais ó bhun go barr.

Próiseáil sonraí

Is cosúil go bhfuil gach rud atá inár n-iarratas réitithe - níl fágtha ach Limit.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Ach anseo tá gach rud simplí - nóid den sórt sin mar Limit, Sort, Aggregate, WindowAgg, Unique “léarscáil” duine le duine do na hoibreoirí comhfhreagracha san iarraidh, má tá siad ann. Níl aon “réaltaí” nó deacrachtaí anseo.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Join

Tagann deacrachtaí chun cinn nuair is mian linn cur le chéile JOIN eatarthu féin. Níl sé seo indéanta i gcónaí, ach is féidir.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Ó thaobh parsálaí an cheist, tá nód againn JoinExpr, a bhfuil go díreach beirt leanaí - chlé agus ar dheis. Is é seo, dá réir sin, atá “os cionn” do bhallraíocht agus a bhfuil scríofa “thíos” san iarratas.

Agus ó thaobh an phlean de, seo dhá shliocht ar chuid acu * Loop/* Join-nód. Nested Loop, Hash Anti Join,... - rud éigin mar sin.

Bainimis úsáid as loighic shimplí: má tá táblaí A agus B againn a “cheanglaíonn” dá chéile sa phlean, ansin san iarratas d’fhéadfaí iad a aimsiú A-JOIN-BB-JOIN-A. Déanaimis iarracht an bealach seo a chomhcheangal, déanaimis iarracht an bealach eile a chur le chéile, agus mar sin de go dtí go rithfimid amach as péirí den sórt sin.

Tógaimis ár gcrann comhréire, tógfaimid ár bplean, féachaimis orthu ... ní cosúil!
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Déanaimis é a tharraingt arís i bhfoirm graif - ó, tá cuma air cheana féin!
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Tabhair faoi deara go bhfuil nóid againn a bhfuil leanaí B agus C ag an am céanna - is cuma linn cén t-ord. A ligean ar le chéile iad agus cas ar an pictiúr den nód os a chionn.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Breathnaímis arís. Anois tá nóid againn le leanaí A agus péirí (B + C) - ag luí leo freisin.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Go hiontach! Tharlaíonn sé go raibh muid an dá JOIN ón iarratas le chéile go rathúil nóid an phlean.

Faraoir, ní réitítear an fhadhb seo i gcónaí.
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Mar shampla, más rud é in iarratas A JOIN B JOIN C, agus sa phlean, ar an gcéad dul síos, ceanglaíodh na nóid “seachtracha” A agus C. Ach níl aon oibreoir den sórt sin san iarratas, níl aon rud le béim againn, níl aon leid le déanamh againn. Tá sé mar an gcéanna leis an "camóg" nuair a scríobhann tú A, B.

Ach, i bhformhór na gcásanna, is féidir beagnach gach nóid a bheith “neamhcheangailte” agus is féidir leat próifíliú den chineál seo a fháil ar thaobh na láimhe clé in am - go litriúil, mar atá in Google Chrome nuair a dhéanann tú anailís ar chód JavaScript. Is féidir leat a fheiceáil cé chomh fada agus a thóg sé gach líne agus gach ráiteas “a fhorghníomhú.”
Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Agus chun é a dhéanamh níos áisiúla duit é seo go léir a úsáid, tá stóráil déanta againn cartlann, áit ar féidir leat do phleananna a shábháil agus níos déanaí a aimsiú mar aon le hiarratais ghaolmhara nó an nasc a roinnt le duine éigin.

Más gá duit ach fiosrúchán neamh-inléite a thabhairt isteach i bhfoirm imleor, bain úsáid as ár “gnáthóir”.

Próifíleoir Fiosrúcháin PostgreSQL: conas plean agus ceist a mheaitseáil

Foinse: will.com

Add a comment