PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Anpil moun ki deja itilize eksplike.tensor.ru - Sèvis vizyalizasyon plan PostgreSQL nou an ka pa okouran de youn nan gwo pouvwa li yo - vire yon moso ki difisil pou li nan jounal sèvè a...

PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch
... nan yon rechèch ki byen fèt ak sijesyon kontèks pou nœuds plan korespondan yo:

PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch
Nan transkripsyon sa a nan dezyèm pati a nan li rapò nan PGConf.Russia 2020 Mwen pral di w ki jan nou jere fè sa.

Ou ka jwenn transkripsyon premye pati a, dedye a pwoblèm pèfòmans rechèch tipik ak solisyon yo, nan atik la "Resèt pou demann SQL malad".



Premyèman, ann kòmanse koloran - epi nou pa pral koloran plan an ankò, nou te deja koulè li, nou deja gen li bèl ak konprann, men yon demann.

Li te sanble pou nou ke ak yon "fèy" san fòma demann lan rale soti nan boutèy la sanble trè lèd ak Se poutèt sa enkonvenyan.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Espesyalman lè devlopè "kole" kò a nan demann lan nan kòd la (sa a se, nan kou, yon antimodèl, men li rive) nan yon sèl liy. Terib!

Ann trase sa a yon jan kanmenm pi bèl.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Men, si nou ka trase sa a trè byen, se sa ki, demonte epi mete ansanm kò a nan demann lan, Lè sa a, nou ka "tache" yon allusion nan chak objè nan demann sa a - sa ki te pase nan pwen ki koresponn lan nan plan an.

Rechèch pye bwa sentaks

Pou fè sa, demann lan dwe premye analize.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Paske nou genyen nwayo a nan sistèm lan kouri sou NodeJS, Lè sa a, nou te fè yon modil pou li, ou kapab jwenn li sou GitHub. An reyalite, sa yo pwolonje "lyezon" nan entèn yo nan analizeur PostgreSQL nan tèt li. Sa vle di, gramè a se tou senpleman binè konpile epi yo fè lyezon yo soti nan NodeJS. Nou te pran modil lòt moun kòm yon baz - pa gen okenn gwo sekrè isit la.

Nou manje kò a nan demann lan kòm opinyon nan fonksyon nou an - nan pwodiksyon an nou jwenn yon pye bwa sentaks analize nan fòm lan nan yon objè JSON.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Koulye a, nou ka kouri nan pye bwa sa a nan direksyon opoze a epi rasanble yon demann ak endentasyon, koloran, ak fòma ke nou vle. Non, sa a se pa customizable, men li te sanble ke sa a ta dwe pratik.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Map rechèch ak plan nœuds

Koulye a, ann wè ki jan nou ka konbine plan an ke nou analize nan premye etap la ak rechèch la ke nou analize nan dezyèm lan.

Ann pran yon egzanp senp - nou gen yon rechèch ki jenere yon CTE epi li li de fwa. Li jenere yon plan konsa.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

CTE

Si w gade li ak anpil atansyon, jiska vèsyon 12 (oswa kòmanse nan li ak mo kle a MATERIALIZED) fòmasyon CTE se yon baryè absoli pou planifikatè a.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Sa vle di ke si nou wè yon jenerasyon CTE yon kote nan demann lan ak yon ne yon kote nan plan an CTE, Lè sa a, nœuds sa yo definitivman "batay" youn ak lòt, nou ka imedyatman konbine yo.

Pwoblèm ak yon asterisk: CTE yo ka enbrike.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch
Gen yo ki trè mal nich, e menm moun ki gen menm non yo. Pou egzanp, ou ka andedan CTE ACTE X, ak nan menm nivo anndan an CTE B fè l 'ankò CTE X:

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

Lè w konpare, ou dwe konprann sa a. Konprann sa a "ak je ou" - menm wè plan an, menm wè kò a nan demann lan - se trè difisil. Si jenerasyon CTE ou a konplèks, enbrike, ak demann yo gwo, Lè sa a, li konplètman san konesans.

UNION

Si nou gen yon mo kle nan rechèch la UNION [ALL] (operatè nan rantre nan de echantiyon), Lè sa a, nan plan an li koresponn ak swa yon ne Append, oswa kèk Recursive Union.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Sa ki "anwo" anlè a UNION - sa a se premye desandan ne nou an, ki se "anba a" - dezyèm lan. Si nan UNION nou gen plizyè blòk "kole" nan yon fwa, lè sa a Append-pral toujou gen yon sèl ne, men li pa pral gen de, men anpil timoun - nan lòd yo ale, respektivman:

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

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

Pwoblèm ak yon asterisk: anndan jenerasyon echantiyon repetitif (WITH RECURSIVE) kapab tou plis pase yon sèl UNION. Men, se sèlman dènye blòk la apre dènye a toujou repete UNION. Tout bagay pi wo a se youn, men diferan UNION:

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

Ou bezwen tou pou kapab "bwase deyò" egzanp sa yo. Nan egzanp sa a nou wè sa UNION-te gen 3 segman nan demann nou an. An konsekans, youn UNION Korespondan Append-node, ak lòt la - Recursive Union.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Done lekti-ekri

Tout bagay yo mete deyò, kounye a nou konnen ki moso nan demann lan koresponn ak ki moso nan plan an. Ak nan moso sa yo nou ka fasilman ak natirèlman jwenn objè sa yo ki "lizib".

Soti nan yon pwen de vi rechèch, nou pa konnen si li se yon tab oswa yon CTE, men yo deziyen pa menm ne la. RangeVar. Ak an tèm de "lizibilite", sa a se tou yon seri nœuds jistis limite:

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

Nou konnen estrikti plan an ak rechèch la, nou konnen korespondans blòk yo, nou konnen non objè yo - nou fè yon konparezon youn a youn.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Ankò travay "ak yon asterisk". Nou pran demann lan, egzekite li, nou pa gen okenn alyas - nou jis li li de fwa nan menm CTE a.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Nou gade nan plan an - ki pwoblèm nan? Poukisa nou te gen yon alyas? Nou pa t kòmande li. Ki kote li jwenn yon "nimewo nimewo" konsa?

PostgreSQL ajoute li tèt li. Ou jis bezwen konprann sa jis tankou yon alyas pou nou, pou rezon konparezon ak plan an, li pa fè okenn sans, li se tou senpleman ajoute isit la. Ann pa fè atansyon sou li.

Dezyèm lan travay "ak yon asterisk": si nou ap li nan yon tab partisyone, Lè sa a, nou pral jwenn yon ne Append oswa Merge Append, ki pral konpoze de yon gwo kantite "timoun", ak chak nan yo ki pral yon jan kanmenm Scan'om soti nan seksyon tab la: Seq Scan, Bitmap Heap Scan oswa Index Scan. Men, nan nenpòt ka, "timoun" sa yo pa pral demann konplèks - sa a se ki jan nœuds sa yo ka distenge ak Append nan UNION.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Nou menm tou nou konprann ne sa yo, kolekte yo "nan yon sèl pil" epi di: "tout sa ou li nan megatable se isit la ak desann pye bwa a".

"Senp" done k ap resevwa nœuds

PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Values Scan koresponn nan plan an VALUES nan demann lan.

Result se yon demann san yo pa FROM sòt de SELECT 1. Oswa lè ou gen yon ekspresyon fè espre fo nan WHERE-block (Lè sa a, atribi a parèt 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 "kat" nan SRF yo ki gen menm non yo.

Men, ak demann enbrike tout bagay se pi konplike - malerezman, yo pa toujou vire nan InitPlan/SubPlan. Pafwa yo tounen ... Join oswa ... Anti Join, sitou lè ou ekri yon bagay tankou WHERE NOT EXISTS .... Ak isit la li pa toujou posib yo konbine yo - nan tèks la nan plan an pa gen okenn operatè ki koresponn ak nœuds yo nan plan an.

Ankò travay "ak yon asterisk": kèk VALUES nan demann lan. Nan ka sa a ak nan plan an ou pral jwenn plizyè nœuds Values Scan.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Sifiks "nimero" pral ede yo fè distenksyon ant yo youn ak lòt - yo ajoute egzakteman nan lòd ki korespondan yo jwenn. VALUES-blòk ansanm demann lan soti anwo jouk anba.

Done pwosesis

Li sanble ke tout bagay nan demann nou an te regle - tout sa ki rete a se Limit.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Men, isit la tout bagay se senp - tankou nœuds tankou Limit, Sort, Aggregate, WindowAgg, Unique "kat" youn-a-yon operatè korespondan yo nan demann lan, si yo la. Pa gen okenn "zetwal" oswa difikilte isit la.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

JOIN

Difikilte rive lè nou vle konbine JOIN ant yo menm. Sa a pa toujou posib, men li posib.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Soti nan pwen de vi analizè rechèch la, nou gen yon ne JoinExpr, ki gen egzakteman de timoun - gòch ak dwa. Sa a, kòmsadwa, se sa ki "pi wo a" JOIN ou a ak sa ki ekri "anba" li nan demann lan.

Ak nan pwen de vi nan plan an, sa yo se de pitit pitit kèk nan * Loop/* Join-ne. Nested Loop, Hash Anti Join,... - yon bagay konsa.

Ann sèvi ak lojik senp: si nou gen tab A ak B ki "rejwenn" youn ak lòt nan plan an, Lè sa a, nan demann lan yo ta ka lokalize swa. A-JOIN-BOswa B-JOIN-A. Ann eseye konbine fason sa a, ann eseye konbine lòt fason alantou, ak sou sa jiskaske nou fini nan pè sa yo.

Ann pran pye bwa sentaks nou an, pran plan nou, gade yo... pa sanble!
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Ann redesine li nan fòm graf - o, li deja sanble ak yon bagay!
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Ann sonje ke nou gen nœuds ki an menm tan gen timoun B ak C - nou pa pran swen nan ki lòd. Ann konbine yo epi vire foto ne a.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Ann gade ankò. Koulye a, nou gen nœuds ak timoun A ak pè (B + C) - konpatib ak yo tou.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Gwo! Li sanble ke nou se de sa yo JOIN soti nan demann lan ak nœuds yo plan yo te konbine avèk siksè.

Ay, pwoblèm sa a pa toujou rezoud.
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Pou egzanp, si nan yon demann A JOIN B JOIN C, ak nan plan an, premye a tout, yo te konekte "eksteryè" nœuds A ak C. Men, pa gen okenn operatè sa yo nan demann lan, nou pa gen anyen mete aksan sou, pa gen anyen yo tache yon allusion. Se menm jan ak "vigil" lè w ekri A, B.

Men, nan pifò ka yo, prèske tout nœuds yo ka "demare" epi ou ka jwenn sa a kalite pwofil sou bò gòch la nan tan - literalman, tankou nan Google Chrome lè ou analize kòd JavaScript. Ou ka wè konbyen tan chak liy ak chak deklarasyon te pran pou "egzekisyon".
PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Ak fè li pi pratik pou ou sèvi ak tout bagay sa yo, nou te fè depo achiv, kote ou ka sove epi pita jwenn plan ou yo ansanm ak demann ki asosye oswa pataje lyen an ak yon moun.

Si ou jis bezwen pote yon rechèch ki pa lizib nan yon fòm adekwat, sèvi ak "normalisateur" nou an.

PostgreSQL Query Profiler: ki jan yo matche ak plan ak rechèch

Sous: www.habr.com

Add nouvo kòmantè