PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Многие, кто уже пользуется explain.tensor.ru - Ntchito yathu yowonera mapulani a PostgreSQL mwina sakudziwa imodzi mwamphamvu zake - kutembenuza chidutswa chovuta kuwerenga cha chipika cha seva ...

PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso
... mufunso lopangidwa mwaluso lokhala ndi malingaliro okhudzana ndi mapulani ofananira:

PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso
Mu cholembedwa ichi cha gawo lachiwiri lake lipoti ku PGConf.Russia 2020 Ndikuuzani momwe tinachitira izi.

Zolemba za gawo loyamba, zoperekedwa ku zovuta zomwe zimachitika pamafunso ndi mayankho awo, zitha kupezeka m'nkhaniyi. "Maphikidwe a mafunso akudwala a SQL".



Choyamba, tiyeni tiyambe kupaka utoto - ndipo sitidzakhalanso mtundu wa pulaniyo, tapaka utoto kale, tili nayo kale yokongola komanso yomveka, koma pempho.

Zinkawoneka kwa ife kuti ndi "tsamba" losasinthika chotere pempho lomwe limachokera ku chipikacho likuwoneka lonyansa kwambiri ndipo chifukwa chake ndi lovuta.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Особенно, когда разработчики в коде «клеят» тело запроса (это, конечно, антипаттерн, но бывает) в одну строку. Жуть!

Давайте это нарисуем как-то более красиво.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Ndipo ngati titha kujambula izi mokongola, ndiye kuti, kugawa ndikubwezeretsanso thupi la pempholo, ndiye kuti "tingaphatikize" lingaliro ku chinthu chilichonse cha pempholi - zomwe zidachitika panthawi yofananira ndi dongosolo.

Funsani mtengo wa syntax

Kuti tichite izi, pempho liyenera kuyankhidwa kaye.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Chifukwa tatero maziko a dongosolo amayendera NodeJS, ndiye tinapanga gawo lake, mutha на GitHub его найти. На самом деле, это является расширенными «биндингами» к внутренностям парсера самого PostgreSQL. То есть просто бинарно скомпилирована грамматика и к ней сделаны биндинги со стороны NodeJS. Мы взяли за основу чужие модули — тут тайны никакой большой нет.

Timadyetsa thupi la pempho monga chothandizira pa ntchito yathu - pazotulutsa timapeza mtengo wa syntax wodulitsidwa ngati chinthu cha JSON.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Tsopano titha kudutsa mumtengowu mbali ina ndikusonkhanitsa pempho ndi ma indents, mitundu, ndi masanjidwe omwe tikufuna. Ayi, izi sizosintha mwamakonda, koma zidawoneka kwa ife kuti izi zitha kukhala zabwino.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Kupanga mapu ndi mapulani node

Tsopano tiyeni tiwone momwe tingaphatikizire dongosolo lomwe tidasanthula mu gawo loyamba ndi funso lomwe tidasanthula lachiwiri.

Tiyeni titenge chitsanzo chosavuta - tili ndi funso lomwe limapanga CTE ndikuwerenga kawiri. Amapanga dongosolo loterolo.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

CTE

Ngati muyang'ana mosamala, mpaka 12 (kapena kuyambira ndi mawu osakira MATERIALIZED) kupanga CTE ndi chotchinga mtheradi kwa wokonza mapulani.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Izi zikutanthauza kuti ngati tiwona mbadwo wa CTE kwinakwake mu pempho ndi node kwinakwake mu dongosolo CTE, ndiye mfundo izi ndithudi "zimamenyana" wina ndi mzake, tikhoza kuziphatikiza nthawi yomweyo.

Vuto ndi nyenyezi: CTEs ikhoza kukhazikitsidwa.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso
Pali zina zomwe sizimakhazikika bwino, komanso za mayina omwewo. Mwachitsanzo, mukhoza mkati CTE A kupanga CTE X, и на том же уровне внутри CTE B chitaninso CTE X:

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

Poyerekeza, muyenera kumvetsetsa izi. Kumvetsetsa izi "ndi maso" - ngakhale kuona dongosolo, ngakhale kuona thupi la pempho - ndi zovuta kwambiri. Ngati m'badwo wanu wa CTE ndi wovuta, wokhala ndi zisa, ndipo zopempha ndi zazikulu, ndiye kuti sizikudziwa.

UNION

Ngati tili ndi mawu osakira mufunso UNION [ALL] (wogwiritsa ntchito kujowina zitsanzo ziwiri), ndiye mu dongosolo limagwirizana ndi node Append, kapena zina Recursive Union.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Zomwe zili "pamwamba" UNION - uyu ndiye mbadwa yoyamba ya node yathu, yomwe ili "pansi" - yachiwiri. Ngati mwadutsa UNION у нас «поклеено» несколько блоков сразу, то Append-padzakhalabe mfundo imodzi yokha, koma sidzakhala ndi awiri, koma ana ambiri - mu dongosolo lomwe amapita, motsatira:

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

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

Vuto ndi nyenyezi: mkati mwa recursive sampling generation (WITH RECURSIVE) тоже может быть больше одного UNION. Koma chipika chomaliza chokha pambuyo pa chomaliza chimakhala chobwerezabwereza UNION. Chilichonse pamwamba ndi chimodzi, koma chosiyana UNION:

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

Такие примеры тоже надо уметь «расклеивать». Вот в этом примере мы видим, что UNION-сегментов в нашем запросе было 3 штуки. Соответственно, одному UNION zimayenderana Append-узел, а другому — Recursive Union.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Werengani-lemba zambiri

Chilichonse chayikidwa, tsopano tikudziwa kuti ndi pempho liti lomwe likufanana ndi gawo la dongosololi. Ndipo mu zidutswa izi tikhoza kupeza mosavuta komanso mwachibadwa zinthu zomwe "zowerengeka".

Kuchokera pamalingaliro amafunso, sitikudziwa ngati ndi tebulo kapena CTE, koma amasankhidwa ndi mfundo yomweyo. RangeVar. Ndipo ponena za "kuwerengeka", iyinso ndi ma node ochepa:

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

Timadziwa dongosolo la ndondomeko ndi funso, timadziwa kugwirizana kwa midadada, timadziwa mayina a zinthu - timafanizirana wina ndi mzake.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Apanso ntchito "ndi nyenyezi". Timatenga pempholi, tikuchita, tilibe zilembo zilizonse - tangowerenga kawiri kuchokera ku CTE yomweyo.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Timayang'ana dongosolo - vuto ndi chiyani? Chifukwa chiyani tinali ndi dzina? Sitinayitanitsa. Kodi “nambala” yoteroyo amaitenga kuti?

PostgreSQL imadziwonjezera yokha. Mukungoyenera kumvetsetsa zimenezo dzina lotere kwa ife, pofuna kufananiza ndi ndondomekoyi, sizikupanga nzeru, zimangowonjezera apa. Tisamumvere iye.

Yachiwiri ntchito "ndi nyenyezi": ngati tikuwerenga kuchokera pa tebulo logawidwa, ndiye kuti tidzapeza mfundo Append kapena Merge Append, yomwe idzakhala ndi chiwerengero chachikulu cha "ana", ndipo chilichonse chidzakhala mwanjira ina Scan'om kuchokera pagawo lagawo: Seq Scan, Bitmap Heap Scan kapena Index Scan. Koma, mulimonse, "ana" awa sadzakhala mafunso ovuta - umu ndi momwe mfundozi zingasiyanitsire Append pa UNION.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Timamvetsetsanso mfundo zoterezi, kuzisonkhanitsa "mu mulu umodzi" ndikuti: "zonse zomwe mumawerenga kuchokera ku megatable zili pano ndi pansi pamtengo".

«Простые» узлы получения данных

PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Values Scan zimayenderana ndi plan VALUES в запросе.

Result — это запрос без FROM monga SELECT 1. Kapena mukakhala ndi mawu onama mwadala WHERE-block (ndiye mawonekedwe amawonekera 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 "mapu" ku ma SRF a dzina lomwelo.

Koma ndi mafunso omwe ali ndi zisa zonse zimakhala zovuta kwambiri - mwatsoka, sizisintha nthawi zonse InitPlan/SubPlan. Иногда они превращаются в ... Join kapena ... Anti Join, makamaka mukalemba zinthu ngati WHERE NOT EXISTS .... Ndipo apa sizingatheke kuziphatikiza - muzolemba za ndondomeko palibe ogwira ntchito omwe akugwirizana ndi mfundo za ndondomekoyi.

Apanso ntchito "ndi nyenyezi": ena VALUES mu pempho. Pankhaniyi ndi dongosolo mudzapeza mfundo zingapo Values Scan.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Zokwanira "zowerengeka" zithandizira kusiyanitsa wina ndi mnzake - zimawonjezedwa ndendende momwe zofananirazo zimapezeka. VALUES-blocks pamodzi pempho kuchokera pamwamba mpaka pansi.

Kukonza deta

Zikuwoneka kuti zonse zomwe tapempha zakonzedwa - zomwe zatsala ndizo Limit.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Koma apa chirichonse chiri chophweka - mfundo monga Limit, Sort, Aggregate, WindowAgg, Unique "mapu" m'modzi-kwa-m'modzi kwa ogwiritsa ntchito omwe akufunsidwa, ngati alipo. Palibe "nyenyezi" kapena zovuta pano.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

ONANI

Zovuta zimachitika tikafuna kuphatikiza JOIN pakati pawo. Izi sizingatheke nthawi zonse, koma ndizotheka.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Kuchokera pamawonedwe a query parser, tili ndi node JoinExpr, у которого ровно два потомка — левый и правый. Это, соответственно, то что «над» вашим JOIN и то что «под» ним в запросе написано.

Ndipo malinga ndi dongosolo, awa ndi ana awiri a ena * Loop/* Join- mfundo. Nested Loop, Hash Anti Join,... - chinachake chonga icho.

Tiyeni tigwiritse ntchito malingaliro osavuta: ngati tili ndi matebulo A ndi B omwe "amalumikizana" wina ndi mnzake mu dongosolo, ndiye muzopempha atha kupezeka mwina. A-JOIN-B, kapena B-JOIN-A. Tiyeni tiyese kuphatikizira motere, tiyeni tiyese kugwirizanitsa njira ina, ndi zina zotero mpaka titatha awiriawiri otere.

Tiyeni titenge mtengo wathu wa syntax, titenge dongosolo lathu, tayang'anani ... osati zofanana!
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Tiyeni tijambulenso ngati ma graph - o, zikuwoneka kale ngati chinachake!
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Tiye tizindikire kuti tili ndi ma node omwe nthawi imodzi amakhala ndi ana B ndi C - sitisamala za dongosolo lotani. Tiyeni tiwaphatikize ndikutembenuza chithunzi cha node.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Посмотрим еще раз. Теперь у нас есть узлы с детьми A и пары (B + C) — совместим и их.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Отлично! Получается, что мы эти два JOIN kuchokera pempho ndi ndondomeko mfundo anali bwino pamodzi.

Tsoka, vuto ili silitha nthawi zonse.
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Mwachitsanzo, ngati mu pempho A JOIN B JOIN C, ndipo mu ndondomekoyi, choyamba, ma node "akunja" A ndi C adagwirizanitsidwa. N'chimodzimodzinso ndi "comma" pamene mukulemba A, B.

Koma, nthawi zambiri, pafupifupi ma node onse amatha "kumasulidwa" ndipo mutha kupeza mbiri yamtunduwu kumanzere munthawi yake - kwenikweni, monga mu Google Chrome mukasanthula kachidindo ka JavaScript. Mutha kuwona kutalika kwa mzere uliwonse ndi chiganizo chilichonse chinatenga "kuchita".
PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Ndipo kuti zikhale zosavuta kuti mugwiritse ntchito zonsezi, tasunga nkhokwe, komwe mungasunge ndikupeza mapulani anu pamodzi ndi zopempha zomwe zikugwirizana nazo kapena kugawana ulalo ndi wina.

Ngati mukungofunika kubweretsa funso losawerengeka mu fomu yokwanira, gwiritsani ntchito "normalizer" wathu.

PostgreSQL Query Profiler: momwe mungagwirizanitse dongosolo ndi funso

Source: www.habr.com

Kuwonjezera ndemanga