ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

NjĂ« pyetje klasike, me tĂ« cilĂ«n zhvilluesi i drejtohet DBA-s sĂ« tij ose pronarit tĂ« biznesit — tĂ« njĂ« kĂ«shilltari pĂ«r PostgreSQL, pothuajse gjithmonĂ« tingĂ«llon e njĂ«jtĂ«: "Pse kĂ«rkesat ekzekutohen kaq ngadalĂ« nĂ« bazĂ«n e tĂ« dhĂ«nave?"

Grupi tradicional i arsyeve:

  • algoritmi joefikas
    kur vendosni të bëni JOIN disa CTE me dhjetëra mijëra regjistra
  • statistika tĂ« prishura
    nëse shpërndarja aktuale e të dhënave në tabelë tashmë ka ndryshuar ndjeshëm nga ajo e mbledhur gjatë ANALYZE në herën e fundit
  • "ndalese" pĂ«r burimet
    dhe tashmë nuk ka burtime të dedikuara të fuqisë kompjuterike, gjigabajtët e memories vazhdojnë të aktivizohen, ose disku nuk arrin të përballojë të gjitha "kënaqësitë" e DB-së
  • bllokime nga proceset konkuruese

Dhe nĂ«se bllokimet janĂ« mjaft tĂ« vĂ«shtira pĂ«r t'u kapur dhe analizuar, pĂ«r gjithçka tjetĂ«r na mjafton plani i kĂ«rkesĂ«s, i cili mund tĂ« merret me anĂ« tĂ« operatĂ«s EXPLAIN (sigurisht, Ă«shtĂ« mĂ« mirĂ« tĂ« bĂ«ni menjĂ«herĂ« EXPLAIN (ANALYZE, BUFFERS) 
) ose modulit auto_explain.

Por, siç thotë po ajo dokumentacion,

"Kuptimi i planit është një art, dhe për ta zotëruar atë, nevojitet një përvojë e caktuar, ..."

Por çfarë mund të kaloni dhe pa të, nëse përdorni një instrument të përshtatshëm!

Si zakonisht duket plani i kërkesës? Diçka si kjo:

Index Scan duke përdorur pg_class_relname_nsp_index në pg_class (koha aktuale=0.049..0.050 rreshta=1 cikle=1)
  Indeksi Kushti: (relname = $1)
  Filtri: (oid = $0)
  Bufra: goditje të ndarë=4
  InitPlan 1 (kthen $0,$1)
    ->  Limit (koha aktuale=0.019..0.020 rreshta=1 cikle=1)
          Bufra: goditje të ndarë=1
          ->  Seq Scan në pg_class pg_class_1 (koha aktuale=0.015..0.015 rreshta=1 cikle=1)
                Filtri: (relkind = 'r'::"char")
                Rreshta të hequr nga Filtri: 5
                Bufra: goditje të ndarë=1

ose kështu:

"Append  (kostos=868.60..878.95 rreshta=2 gjerësi=233) (koha aktuale=0.024..0.144 rreshta=2 cikle=1)"
"  Bufra: goditje të ndarë=3"
"  CTE cl"
"    ->  Seq Scan në pg_class  (kostos=0.00..868.60 rreshta=9972 gjerësi=537) (koha aktuale=0.016..0.042 rreshta=101 cikle=1)"
"          Bufra: goditje të ndarë=3"
"  ->  Limit  (kostos=0.00..0.10 rreshta=1 gjerësi=233) (koha aktuale=0.023..0.024 rreshta=1 cikle=1)"
"        Bufra: goditje të ndarë=1"
"        ->  CTE Scan në cl  (kostos=0.00..997.20 rreshta=9972 gjerësi=233) (koha aktuale=0.021..0.021 rreshta=1 cikle=1)"
"              Bufra: goditje të ndarë=1"
"  ->  Limit  (kostos=10.00..10.10 rreshta=1 gjerësi=233) (koha aktuale=0.117..0.118 rreshta=1 cikle=1)"
"        Bufra: goditje të ndarë=2"
"        ->  CTE Scan në cl cl_1  (kostos=0.00..997.20 rreshta=9972 gjerësi=233) (koha aktuale=0.001..0.104 rreshta=101 cikle=1)"
"              Bufra: goditje të ndarë=2"
"Koha e Planifikimit: 0.634 ms"
"Koha e Ekzekutimit: 0.248 ms"

Por tĂ« lexosh planin me fjalĂ« "nga fletĂ«" — Ă«shtĂ« shumĂ« e vĂ«shtirĂ« dhe jofshikueshme:

  • nĂ« nyjĂ« jepet shuma sipas burimeve tĂ« nĂ«npemĂ«s
    pra tĂ« kuptoni se sa kohĂ« ka marrĂ« realizimi i njĂ« nyjeje tĂ« caktuar, ose sa saktĂ«sisht ky lexim nga tabela ka nxjerrĂ« tĂ« dhĂ«na nga disku — duhet nĂ« njĂ«farĂ« mĂ«nyre tĂ« zbresim njĂ« nga tjetra
  • koha e nyjes Ă«shtĂ« e nevojshme tĂ« shumĂ«zohet me loops
    po, zbritja akoma nuk Ă«shtĂ« operacioni mĂ« i komplikuar qĂ« duhet bĂ«rĂ« «nĂ« mendje» — sepse koha e realizimit jepet mesatare pĂ«r njĂ« realizim tĂ« nyjes, dhe ato mund tĂ« jenĂ« qindra
  • aty e gjithĂ« kjo bashkĂ« pengon pĂ«rgjigjen e pyetjes kryesore — kush Ă«shtĂ« «lidhja mĂ« e dobĂ«t»?

Kur përpiqeshim të shpjegonim të gjitha këto disa qindra zhvilluesve tanë, kuptuam se nga jashtë kjo duket më pak si kjo:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

A, pra, na nevojitet...

Instrument

Këtu përpiqemi të mbledhim të gjithë mekanizmat kryesorë që ndihmojnë sipas planit dhe kërkesës për të kuptuar «kush është fajtor dhe çfarë duhet bërë». Po ashtu, të ndajmë një pjesë të përvojës tonë me komunitetin.
MirĂ« se vini dhe pĂ«rdorni — explain.tensor.ru

Klarësia e planeve

A është e lehtë të kuptohet plani kur ai duket kështu?

Seq Scan on pg_class (koha reale=0.009..1.304 rreshta=6609 loops=1)
  Buffers: shared hit=263
Koha e Planifikimit: 0.108 ms
Koha e Ekzekutimit: 1.800 ms

Jo shumë.

Por kĂ«shtu, nĂ« formĂ« tĂ« shkurtuar, kur treguesit kryesorĂ« janĂ« tĂ« ndarĂ« — tashmĂ« Ă«shtĂ« shumĂ« mĂ« e kuptueshme:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

Porë që plani të jetë më kompleks, ndihma do të vijë diagrame e shpërndarjes së kohës sipër nodeve:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

Po, për opsionet më të komplikuara, ndihmën e sjell diagrame e ekzekutimit:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

Për shembull, ka situata mjaft jo-triviale kur plani mund të ketë më shumë se një rrënjë të vërtetë:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atëÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

Sugjerimet strukturore

Po, nĂ«se e gjithĂ« struktura e planit dhe dobĂ«sitĂ« e tij janĂ« ndarĂ« dhe tĂ« dukshme — pse tĂ« mos i ndriçojmĂ« ato pĂ«r zhvilluesin dhe tĂ« shpjegojmĂ« me "gjuhĂ« tĂ« thjeshtĂ«"?

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«TĂ« tilla shabllone rekomandimesh ne kemi mbledhur tashmĂ« disa dhjetĂ«ra.

Profilizuesi rresht për kërkesat

Tani, nĂ«se i aplikoni kĂ«rkesĂ«s fillestare planit qĂ« po analizohet, do tĂ« shihni sa kohĂ« ka kaluar pĂ«r secilin operator tĂ« veçantĂ« — pĂ«rafĂ«rsisht kĂ«shtu:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«


 ose madje kështu:

ÇfarĂ« flet EXPLAIN, dhe si ta bisedojmĂ« atĂ«

Zëvendësimi i parametrave në kërkesë

Nëse "kefshë" kërkesën tuaj dhe parametrat e saj nga rreshti DETAIL të logut, do të jeni në gjendje ta kopjoni atë për më tej në një nga variantet:

  • me zĂ«vendĂ«simin e vlerave nĂ« kĂ«rkesĂ«
    për ekzekutim të menjëhershëm në bazën tuaj dhe për profilizim të mëtejshëm
    SELECT 'const', 'param'::text;
  • me zĂ«vendĂ«simin e vlerave pĂ«rmes PREPARE/EXECUTE
    pĂ«r tĂ« simuluar funksionimin e planifikuesit, kur pjesa parametrike mund tĂ« injorohet — pĂ«r shembull, kur punoni me tabela tĂ« ndara
    DEALLOCATE ALL;
    PREPARE q(text) AS SELECT 'const', $1::text;
    EXECUTE q('param'::text);
    

Arkivi i planeve

Shtoni, analizoni, ndani me kolegët! Planet do të mbeten në arkiv dhe ju do të keni mundësi të ktheheni te to më vonë: explain.tensor.ru/archive

Por nĂ«se nuk dĂ«shironi qĂ« plani juaj tĂ« shihet nga tĂ« tjerĂ«t, mos harroni tĂ« vendosni shenjĂ«n „mos e publikoni nĂ« arkiv“.

Në artikujt e ardhshëm do të flas për ato vështirësi dhe zgjidhje që ndodhin gjatë analizimit të planit.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster