Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Mòran a tha mar-thà a 'cleachdadh mìnich.tensor.ru - is dòcha nach eil an t-seirbheis fradharc plana PostgreSQL againn mothachail air aon de na mòr-chumhachdan aige - a’ tionndadh pìos de log an fhrithealaiche a tha doirbh a leughadh...

Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist
... a-steach do cheist air a dhealbhadh gu breagha le molaidhean co-theacsail airson na nodan plana co-fhreagarrach:

Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist
Anns an ath-sgrìobhadh seo den dàrna pàirt de a aithisg aig PGConf.Russia 2020 Innsidh mi dhut mar a chaidh againn air seo a dhèanamh.

Gheibhear tar-sgrìobhadh na ciad phàirt, a tha coisrigte do dhuilgheadasan coileanaidh ceist àbhaisteach agus na fuasglaidhean aca, san artaigil "Reasabaidhean airson ceistean SQL tinn".



An toiseach, tòisichidh sinn a ’dathadh - agus cha bhith sinn a’ dath a ’phlana tuilleadh, tha sinn air a dhath mu thràth, tha e brèagha agus so-thuigsinn againn mu thràth, ach iarrtas.

Bha e coltach dhuinn le “duilleag” cho neo-chruthaichte gu bheil an t-iarrtas a chaidh a tharraing bhon log a’ coimhead gu math grànda agus mar sin mì-ghoireasach.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Gu sònraichte nuair a bhios luchd-leasachaidh “a’ glaodhadh ”corp an iarrtais anns a’ chòd (tha seo, gu dearbh, na antipattern, ach tha e a ’tachairt) ann an aon loidhne. Uamhasach!

Tarraingidh sinn seo dòigh air choireigin nas bòidhche.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Agus mas urrainn dhuinn seo a tharraing gu breagha, is e sin, corp an iarrtais a thoirt air falbh agus a chuir air ais ri chèile, faodaidh sinn an uairsin “beachd” a cheangal ri gach nì den iarrtas seo - dè thachair aig an ìre fhreagarrach sa phlana.

Ceist syntax craobh

Gus seo a dhèanamh, feumaidh an t-iarrtas a bhith air a pharsadh an toiseach.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

A chionn gu bheil againn tha cridhe an t-siostaim a’ ruith air NodeJS, an uairsin rinn sinn modal air a shon, faodaidh tu lorg e air GitHub. Gu dearbh, tha iad sin nan “ceanglaichean” air an leudachadh gu taobh a-staigh parser PostgreSQL fhèin. Is e sin, tha an gràmar dìreach air a chur ri chèile le dàna agus tha ceangalaichean ga dhèanamh bho NodeJS. Ghabh sinn modalan dhaoine eile mar bhunait - chan eil dìomhaireachd mòr an seo.

Bidh sinn a’ biathadh corp an iarrtais mar chur-a-steach don obair againn - aig an toradh gheibh sinn craobh co-chòrdadh parsed ann an cruth nì JSON.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

A-nis is urrainn dhuinn ruith tron ​​​​chraobh seo an taobh eile agus iarrtas a chruinneachadh leis na indents, dathadh agus cruth a tha sinn ag iarraidh. Chan e, chan eil seo gnàthaichte, ach bha e coltach dhuinn gum biodh seo goireasach.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Ceist mapaidh agus nodan plana

A-nis chì sinn mar as urrainn dhuinn am plana a mhion-sgrùdadh sa chiad cheum agus a’ cheist a rinn sinn mion-sgrùdadh san dàrna fear a chur còmhla.

Gabhamaid eisimpleir shìmplidh - tha ceist againn a ghineas CTE agus a leughas bhuaithe dà uair. Bidh e a’ cruthachadh a leithid de phlana.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

CTE

Ma choimheadas tu air gu faiceallach, suas gu dreach 12 (no a’ tòiseachadh leis leis a’ phrìomh fhacal MATERIALIZED) cruthachadh Tha CTE na chnap-starra iomlan don neach-dealbhaidh.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Tha seo a’ ciallachadh ma chì sinn ginealach CTE an àiteigin san iarrtas agus nód an àiteigin sa phlana CTE, an uairsin bidh na nodan sin gu cinnteach “a’ sabaid ”ri chèile, is urrainn dhuinn an cur còmhla sa bhad.

Trioblaid le rionnag: Faodar CTEn a neadachadh.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist
Tha neadan glè bhochd ann, agus eadhon feadhainn den aon ainm. Mar eisimpleir, faodaidh tu a-staigh CTE A dèan CTE X, agus aig an aon ìre a-staigh CTE B dèan a-rithist e CTE X:

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

Nuair a thathar a’ dèanamh coimeas, feumaidh tu seo a thuigsinn. Tha e glè dhoirbh seo a thuigsinn “le do shùilean” - eadhon am plana fhaicinn, eadhon corp an iarrtais fhaicinn. Ma tha do ghinealach CTE iom-fhillte, neadaichte, agus gu bheil na h-iarrtasan mòr, tha e gu tur gun mhothachadh.

AONADH

Ma tha prìomh fhacal againn sa cheist UNION [ALL] (gnìomhaiche a bhith a 'ceangal dà shampall), an uairsin anns a' phlana tha e a 'freagairt ri nód Append, no cuid Recursive Union.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

An rud a tha “gu h-àrd” gu h-àrd UNION - is e seo a 'chiad shliochd de ar nód, a tha "gu h-ìosal" - an dàrna. Ma tha troimhe UNION tha grunn bhlocaichean againn “glued” aig an aon àm, ma-thà Append- Cha bhi ach aon nód ann fhathast, ach cha bhi dithis ann, ach mòran chloinne - san òrdugh a thèid iad, fa leth:

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

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

Trioblaid le rionnag: ginealach samplachaidh ath-chuairteach taobh a-staigh (WITH RECURSIVE) cuideachd a bhith nas motha na aon UNION. Ach chan eil ach am bloc mu dheireadh às deidh an tè mu dheireadh an-còmhnaidh ath-chuairteach UNION. Tha a h-uile dad gu h-àrd mar aon, ach eadar-dhealaichte UNION:

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

Feumaidh tu cuideachd a bhith comasach air “cumail a-mach” eisimpleirean mar sin. Anns an eisimpleir seo chì sinn sin UNION- bha 3 earrann anns an iarrtas againn. A rèir sin, aon UNION соответствует Append-node, agus dhan fhear eile - Recursive Union.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Leugh-sgrìobh dàta

Tha a h-uile càil air a dhealbhadh, a-nis tha fios againn dè am pìos den iarrtas a fhreagras ris a’ phìos den phlana. Agus anns na pìosan seo is urrainn dhuinn na stuthan sin a tha “so-leughaidh” a lorg gu furasta agus gu nàdarra.

Bho shealladh ceist, chan eil fios againn an e bòrd no CTE a th’ ann, ach tha iad air an comharrachadh leis an aon nód RangeVar. Agus a thaobh “leughaidh”, tha seo cuideachd na sheata de nodan gu math cuibhrichte:

  • 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]

Tha fios againn air structar a’ phlana agus a’ cheist, tha fios againn air litrichean nam blocaichean, tha fios againn air ainmean nan nithean - bidh sinn a’ dèanamh coimeas aon-ri-aon.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

A-rithist obair "le rionnag". Gabhaidh sinn an t-iarrtas, cuir an gnìomh e, chan eil ailias sam bith againn - bidh sinn dìreach ga leughadh dà uair bhon aon CTE.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Bheir sinn sùil air a’ phlana – dè an duilgheadas a th’ ann? Carson a bha ailias againn? Cha do dh'òrdaich sinn e. Càite am faigh e a leithid de “àireamh àireamh”?

Tha PostgreSQL ga chur ris fhèin. Feumaidh tu dìreach sin a thuigsinn dìreach a leithid de alias dhuinne, airson adhbharan coimeas ris a’ phlana, chan eil e a’ dèanamh ciall sam bith, tha e dìreach air a chur ris an seo. Nach toir sinn an aire dha.

An dàrna fear obair "le rionnag": ma tha sinn a' leughadh o bhòrd dealaichte, gheibh sinn nód Append no Merge Append, anns am bi àireamh mhòr de “chlann”, agus bidh gach fear dhiubh ann an dòigh air choireigin Scan'om bho earrann a' bhùird: Seq Scan, Bitmap Heap Scan no Index Scan. Ach, co-dhiù, cha bhi na “clann” sin nan ceistean iom-fhillte - seo mar a dh’ aithnichear na nodan sin Append aig UNION.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Bidh sinn cuideachd a 'tuigsinn nan snaidhmean sin, cruinnich iad "ann an aon chrann" agus abair: "tha a h-uile dad a leughas tu bho megatable an seo agus sìos a’ chraoibh".

Dàta "sìmplidh" a 'faighinn nodan

Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Values Scan a’ freagairt sa phlana VALUES anns an iarrtas.

Result 's e iarrtas gun FROM mar SELECT 1. No nuair a tha abairt meallta agad a dh’aona ghnothach ann an WHERE-block (an uairsin nochdaidh am feart 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 “mapa” gu na SRFn den aon ainm.

Ach le ceistean neadachaidh tha a h-uile dad nas iom-fhillte - gu mì-fhortanach, chan eil iad daonnan a 'tionndadh a-steach InitPlan/SubPlan. Uaireannan bidh iad a 'tionndadh a-steach ... Join no ... Anti Join, gu sònraichte nuair a sgrìobhas tu rudeigin mar sin WHERE NOT EXISTS .... Agus an seo chan eil e an-còmhnaidh comasach an cur còmhla - ann an teacsa a 'phlana chan eil gnìomhaichean ann a fhreagras ri nodan a' phlana.

A-rithist obair "le rionnag": cuid VALUES anns an iarrtas. Anns a 'chùis seo agus anns a' phlana gheibh thu grunn nodan Values Scan.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Cuidichidh iar-leasachan “àireamhaichte” gus an dealachadh bho chèile - tha iad air an cur dìreach san òrdugh anns an lorgar an fheadhainn fhreagarrach VALUES-blocaichean air feadh an iarrtais bho mhullach gu bonn.

Giullachd dàta

Tha e coltach gu bheil a h-uile dad nar n-iarrtas air a rèiteachadh - chan eil air fhàgail Limit.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Ach an seo tha a h-uile dad sìmplidh - leithid nodan mar Limit, Sort, Aggregate, WindowAgg, Unique “mapa” aon-ri-aon dha na gnìomhaichean co-fhreagarrach san iarrtas, ma tha iad ann. Chan eil “rionnagan” no duilgheadasan an seo.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Co-aoinn

Bidh duilgheadasan ag èirigh nuair a tha sinn airson a dhol còmhla JOIN eatorra fein. Chan eil seo an-còmhnaidh comasach, ach tha e comasach.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Bho shealladh parser na ceiste, tha nód againn JoinExpr, aig a bheil dìreach dithis chloinne - clì is deas. Is e seo, a rèir sin, a tha “os cionn” do JOIN agus na tha sgrìobhte “gu h-ìosal” anns an iarrtas.

Agus bho thaobh a’ phlana, ’s iad seo dithis de shliochd cuid * Loop/* Join-nòs. Nested Loop, Hash Anti Join,... - rudeigin mar sin.

Cleachdaidh sinn loidsig shìmplidh: ma tha clàran A agus B againn a bhios “a’ ceangal ”ri chèile sa phlana, an uairsin san iarrtas dh’ fhaodadh iad a bhith air an lorg an dàrna cuid A-JOIN-B, no B-JOIN-A. Feuchaidh sinn ris an dòigh seo a chur còmhla, feuchaidh sinn ris an dòigh eile a chur còmhla, agus mar sin air adhart gus an ruith sinn a-mach à càraidean mar sin.

Gabhamaid ar craobh cho-aontachaidh, gabh ar plana, coimhead orra ... chan eil e coltach!
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Feuch an ath-tharraing sinn e ann an cruth ghrafaichean - o, tha e coltach ri rudeigin mu thràth!
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Thoir an aire gu bheil nodan againn aig a bheil clann B agus C aig an aon àm - chan eil dragh againn dè an òrdugh. Nach cuir sinn còmhla iad agus tionndaidh sinn dealbh an nód.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Bheir sinn sùil a-rithist. A-nis tha nodan againn le clann A agus paidhrichean (B + C) - co-chòrdail riutha cuideachd.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Sgoinneil! Tha e a’ tionndadh a-mach gur sinne an dithis seo JOIN bhon iarrtas le nodan a’ phlana air an cur còmhla gu soirbheachail.

Gu fortanach, chan eil an duilgheadas seo daonnan air a rèiteachadh.
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Mar eisimpleir, ma tha e ann an iarrtas A JOIN B JOIN C, agus anns a 'phlana, an toiseach, bha na nodan "taobh a-muigh" A agus C ceangailte. Ach chan eil an leithid de ghnìomhaiche san iarrtas, chan eil dad againn ri chomharrachadh, chan eil dad ann airson sanas a cheangal. Tha e an aon rud ris a’ “choma” nuair a bhios tu a’ sgrìobhadh A, B.

Ach, sa mhòr-chuid de chùisean, faodaidh cha mhòr a h-uile nodan a bhith “gun cheangal” agus gheibh thu an seòrsa pròifil seo air an taobh chlì ann an ùine - gu litearra, mar ann an Google Chrome nuair a nì thu mion-sgrùdadh air còd JavaScript. Chì thu dè cho fada ‘s a thug gach loidhne agus gach aithris“ a chuir gu bàs. ”
Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Agus airson a dhèanamh nas goireasaiche dhut seo uile a chleachdadh, tha sinn air stòradh a dhèanamh tasglann, far an urrainn dhut do phlanaichean a shàbhaladh agus nas fhaide air adhart a lorg còmhla ri iarrtasan co-cheangailte riutha no an ceangal a cho-roinn le cuideigin.

Ma dh’ fheumas tu dìreach ceist nach gabh leughadh a thoirt a-steach ann an cruth iomchaidh, cleachd ar “normalizer”.

Pròifil ceist PostgreSQL: mar a nì thu maidseadh plana agus ceist

Source: www.habr.com

Cuir beachd ann