Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Klassikaline küsimus, mille arendaja esitab oma DBA-le või ettevõtte omanik PostgreSQL-i konsultandile, kõlab peaaegu alati samamoodi: "Miks võtab taotluste täitmine andmebaasis nii kaua aega?"

Traditsiooniline põhjuste komplekt:

  • ebaefektiivne algoritm
    kui otsustate LIITUDA mitme CTE-ga üle paarikümne tuhande plaadi
  • ebaoluline statistika
    kui andmete tegelik jaotus tabelis on juba väga erinev eelmisel korral ANALYZE kogutud andmetest
  • "pistikuga" ressursse
    ja protsessoril pole enam piisavalt arvutusvõimsust, gigabaite pumbatakse pidevalt mälu või ketas ei suuda täita kõiki andmebaasi "soove"
  • blokeerimine konkureerivatest protsessidest

Ja kui blokeeringuid on üsna raske tabada ja analüüsida, siis kõige muu jaoks, mida vajame päringu plaan, mille saab hankida kasutades SELGITA operaatorit (Parem on muidugi kohe SELGITADA (ANALÜÜSI, PUHVERID) ...) või auto_explain moodul.

Kuid nagu samas dokumentides öeldud,

"Plaanist aru saamine on kunst ja selle valdamine nõuab teatud kogemust..."

Kuid saate ilma selleta hakkama, kui kasutate õiget tööriista!

Kuidas päringuplaan tavaliselt välja näeb? Midagi sellist:

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

või niimoodi:

"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"

Kuid kava lugemine tekstis "lehelt" on väga raske ja ebaselge:

  • kuvatakse sõlmes summa alampuu ressursside kaupa
    see tähendab, et mõista, kui palju aega kulus konkreetse sõlme käivitamiseks või kui palju täpselt see tabelist lugemine tõi kettalt andmeid, tuleb üks teisest kuidagi lahutada.
  • sõlme aega on vaja korrutada silmustega
    jah, lahutamine ei ole kõige keerulisem toiming, mida tuleb "peas" teha - lõppude lõpuks on täitmisaeg näidatud sõlme ühe täitmise keskmisena ja neid võib olla sadu
  • noh, ja see kõik kokku ei lase meil vastata põhiküsimusele – kes siis "nõrgem lüli"?

Kui proovisime seda kõike mitmesajale arendajale selgitada, mõistsime, et väljastpoolt nägi see välja umbes selline:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Ja see tähendab, et me vajame...

Vahend

Sellesse püüdsime vastavalt plaanile ja soovile kokku koguda kõik võtmemehaanikad, mis aitavad aru saada, “kes on süüdi ja mida teha”. Ja jagage osa oma kogemusest kogukonnaga.
Tutvuge ja kasutage - selgitus.tensor.ru

Plaanide nähtavus

Kas plaanist on lihtne aru saada, kui see välja näeb?

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

Mitte päris.

Aga niimoodi, lühendatud kujulkui põhinäitajad on eraldatud, on see palju selgem:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Aga kui plaan on keerulisem, tuleb ta appi diagrammi ajajaotus sõlmede järgi:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Noh, kõige raskemate võimaluste puhul kiirustab ta aitama edenemise graafik:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Näiteks on üsna mittetriviaalseid olukordi, kus plaanil võib olla rohkem kui üks tegelik juur:

Millest EXPLAIN vaikib ja kuidas see kõnelema pannaMillest EXPLAIN vaikib ja kuidas see kõnelema panna

Struktuursed vihjed

Noh, kui kogu planeeringu struktuur ja selle valulikud kohad on juba paika pandud ja nähtavad, siis miks mitte need arendajale esile tõsta ja “vene keeles” selgitada?

Millest EXPLAIN vaikib ja kuidas see kõnelema pannaOleme kogunud juba paarkümmend sellist soovitusmalli.

Rea-realt päringuprofiili koostaja

Nüüd, kui lisate esialgse päringu analüüsitud plaanile, näete, kui palju aega kulus igale avaldusele – umbes selline:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

...või isegi nii:

Millest EXPLAIN vaikib ja kuidas see kõnelema panna

Parameetrite asendamine päringuga

Kui lisasite plaanile mitte ainult taotluse, vaid ka selle parameetrid logi realt DETAIL, saate selle lisaks kopeerida ühes järgmistest valikutest:

  • väärtuse asendusega päringus
    otseseks täitmiseks teie baasil ja edasiseks profileerimiseks

    SELECT 'const', 'param'::text;
  • väärtuse asendusega PREPARE/EXECUTE kaudu
    ajakava töö jäljendamiseks, kui parameetrilist osa saab ignoreerida - näiteks partitsioonitud tabelitega töötades

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

Plaanide arhiiv

Kleepige, analüüsige, jagage kolleegidega! Plaanid jäävad arhiivi ja saate nende juurde hiljem naasta: selgitus.tensor.ru/archive

Kuid kui te ei soovi, et teised teie plaani näeksid, ärge unustage märkida kasti "Ära avalda arhiivis".

Järgmistes artiklites räägin plaani analüüsimisel tekkivatest raskustest ja otsustest.

Allikas: www.habr.com

Lisa kommentaar