Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

Pyetja klasike që një zhvillues i bën DBA-së së tij ose një pronar biznesi i sjell një konsulenti PostgreSQL pothuajse gjithmonë tingëllon e njëjta: "Pse kërkesat kërkojnë kaq shumë kohë për të përfunduar në bazën e të dhënave?"

Një grup arsyesh tradicionale:

  • algoritmi joefikas
    kur vendosni të BASHKONI në disa CTE mbi disa dhjetëra mijëra rekorde
  • statistika të vjetruara
    nëse shpërndarja aktuale e të dhënave në tabelë është tashmë shumë e ndryshme nga ajo e mbledhur nga ANALYZE herën e fundit
  • "prizë" në burime
    dhe nuk ka më fuqi të mjaftueshme llogaritëse të dedikuar të CPU-së, gigabajt memorie pompohen vazhdimisht, ose disku nuk mund të vazhdojë me të gjitha "dëshirat" e bazës së të dhënave
  • bllokimi nga proceset konkurruese

Dhe nëse bllokimet janë mjaft të vështira për t'u kapur dhe analizuar, atëherë për gjithçka tjetër që na nevojitet plani i pyetjes, të cilat mund të merren duke përdorur SHPJEGON operatori (Është më mirë, natyrisht, që menjëherë të shpjegohet (ANALIZO, BUFFER) ...) ose moduli auto_explain.

Por, siç thuhet në të njëjtin dokumentacion,

"Të kuptosh një plan është një art dhe për ta zotëruar atë kërkon një sasi të caktuar eksperience..."

Por ju mund të bëni pa të nëse përdorni mjetin e duhur!

Si duket zakonisht një plan pyetjesh? Diçka e tillë:

Index Scan using pg_class_relname_nsp_index on pg_class (actual time=0.049..0.050 rows=1 loops=1)
  Index Cond: (relname = $1)
  Filter: (oid = $0)
  Buffers: shared hit=4
  InitPlan 1 (returns $0,$1)
    ->  Limit (actual time=0.019..0.020 rows=1 loops=1)
          Buffers: shared hit=1
          ->  Seq Scan on pg_class pg_class_1 (actual time=0.015..0.015 rows=1 loops=1)
                Filter: (relkind = 'r'::"char")
                Rows Removed by Filter: 5
                Buffers: shared hit=1

ose si kjo:

"Append  (cost=868.60..878.95 rows=2 width=233) (actual time=0.024..0.144 rows=2 loops=1)"
"  Buffers: shared hit=3"
"  CTE cl"
"    ->  Seq Scan on pg_class  (cost=0.00..868.60 rows=9972 width=537) (actual time=0.016..0.042 rows=101 loops=1)"
"          Buffers: shared hit=3"
"  ->  Limit  (cost=0.00..0.10 rows=1 width=233) (actual time=0.023..0.024 rows=1 loops=1)"
"        Buffers: shared hit=1"
"        ->  CTE Scan on cl  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.021..0.021 rows=1 loops=1)"
"              Buffers: shared hit=1"
"  ->  Limit  (cost=10.00..10.10 rows=1 width=233) (actual time=0.117..0.118 rows=1 loops=1)"
"        Buffers: shared hit=2"
"        ->  CTE Scan on cl cl_1  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.001..0.104 rows=101 loops=1)"
"              Buffers: shared hit=2"
"Planning Time: 0.634 ms"
"Execution Time: 0.248 ms"

Por leximi i planit në tekst "nga fleta" është shumë i vështirë dhe i paqartë:

  • shfaqet në nyje shuma sipas burimeve të nënpemës
    domethënë, për të kuptuar se sa kohë u desh për të ekzekutuar një nyje të caktuar, ose sa saktësisht ky lexim nga tabela solli të dhëna nga disku, duhet të zbrisni disi njërën nga tjetra.
  • nevojitet koha e nyjës shumohen me sythe
    po, zbritja nuk është operacioni më kompleks që duhet të bëhet "në kokë" - në fund të fundit, koha e ekzekutimit tregohet si mesatare për një ekzekutim të një nyje, dhe mund të ketë qindra prej tyre
  • mirë, dhe e gjithë kjo së bashku na pengon t'i përgjigjemi pyetjes kryesore - pra kush "Lidhja më e dobët"?

Kur u përpoqëm t'ua shpjegonim gjithë këtë disa qindra zhvilluesve tanë, kuptuam se nga jashtë dukej diçka si kjo:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

Dhe kjo do të thotë se ne kemi nevojë ...

Mjet

Në të u përpoqëm të mbledhim të gjithë mekanikët kryesorë që ndihmojnë, sipas planit dhe kërkesës, për të kuptuar "kush duhet të fajësohet dhe çfarë të bëjë". Epo, dhe ndani një pjesë të përvojës tuaj me komunitetin.
Takohuni dhe përdorni - shpjegoj.tensor.ru

Dukshmëria e planeve

A është e lehtë të kuptosh planin kur duket kështu?

Seq Scan on pg_class (actual time=0.009..1.304 rows=6609 loops=1)
  Buffers: shared hit=263
Planning Time: 0.108 ms
Execution Time: 1.800 ms

Jo me të vërtetë.

Por si kjo, në formë të shkurtuarkur treguesit kryesorë janë të ndarë, është shumë më e qartë:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

Por nëse plani është më i ndërlikuar, ai do të vijë në shpëtim shpërndarja e kohës piechart sipas nyjeve:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

Epo, për opsionet më të vështira ai është me nxitim për të ndihmuar grafiku i progresit:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

Për shembull, ka situata mjaft jo të parëndësishme kur një plan mund të ketë më shumë se një rrënjë aktuale:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalëPër çfarë EXPLAIN hesht dhe si të bëhet fjalë

Të dhëna strukturore

Epo, nëse e gjithë struktura e planit dhe pikat e tij të dhimbshme janë tashmë të përcaktuara dhe të dukshme, pse të mos i nënvizoni ato te zhvilluesi dhe t'i shpjegoni ato në "gjuhën ruse"?

Për çfarë EXPLAIN hesht dhe si të bëhet fjalëNe kemi mbledhur tashmë nja dy duzina modele të tilla rekomandimi.

Profilizuesi i pyetjeve rresht pas rreshti

Tani, nëse mbivendosni pyetjen origjinale në planin e analizuar, mund të shihni se sa kohë është shpenzuar për secilën deklaratë individuale - diçka si kjo:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

...apo edhe si kjo:

Për çfarë EXPLAIN hesht dhe si të bëhet fjalë

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

Nëse "bashkëngjitni" jo vetëm një kërkesë në plan, por edhe parametrat e saj nga rreshti DETAIL i regjistrit, mund ta kopjoni gjithashtu në një nga opsionet:

  • me zëvendësim të vlerës në pyetje
    për ekzekutimin e drejtpërdrejtë në bazën tuaj dhe profilizimin e mëtejshëm

    SELECT 'const', 'param'::text;
  • me zëvendësim të vlerës nëpërmjet PREPARE/EXECUTE
    për të imituar punën e planifikuesit, kur pjesa parametrike mund të injorohet - për shembull, kur punoni në tabela të ndara

    DEALLOCATE ALL;
    PREPARE q(text) AS SELECT 'const', $1::text;
    EXECUTE q('param'::text);
    

Arkivi i planeve

Ngjitni, analizoni, ndajeni me kolegët! Planet do të mbeten të arkivuara dhe ju mund t'u ktheheni më vonë: shpjegoj.tensor.ru/archive

Por nëse nuk dëshironi që të tjerët ta shohin planin tuaj, mos harroni të kontrolloni kutinë "mos boto në arkiv".

Në artikujt e mëposhtëm do të flas për vështirësitë dhe vendimet që dalin gjatë analizimit të një plani.

Burimi: www.habr.com

Shto një koment