La klasika demando, kiun programisto demandas al sia administranto-administranto aŭ entreprenposedanto al konsultisto de PostgreSQL, preskaŭ ĉiam estas la sama: "Kial serĉoj daŭras tiom longe por funkcii en la datumbazo?"
Tradicia aro de kialoj:
- malefika algoritmo
kiam vi decidas ALIĜI al pluraj CTE-oj super kelkaj dekmiloj da registroj - senrilataj statistikoj
se la efektiva distribuo de datumoj en la tabelo jam estas tre malsama ol tiu kolektita de ANALYZE lastfoje - "ŝtopilo" sur rimedoj
kaj jam ne estas sufiĉe da dediĉita komputila povo de la procesoro, gigabajtoj da memoro estas konstante pumpataj, aŭ la disko ne povas plenumi ĉiujn "bezonojn" de la datumbazo - blokado de konkurantaj procezoj
Kaj se blokadojn estas sufiĉe malfacile kapti kaj analizi, tiam por ĉio alia ni nur bezonas serĉplano, kiun oni povas akiri per (Kompreneble, estas pli bone tuj KLARIGI (ANALIZI, BUFROJ) ...) aŭ .
Sed, kiel deklarite en la sama dokumentaro,
"Kompreni planon estas arto, kaj por majstri ĝin necesas certa kvanto da sperto, ..."
Sed vi povas rezigni pri ĝi se vi uzas la ĝustan ilon!
Kiel kutime aspektas serĉplano? Io simila al ĉi tio:
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=1aŭ tiel:
"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"Sed legi planon en teksto "el folio" estas tre malfacile kaj ne vide:
- en la nodo estas montrata sumo de subarbaj rimedoj
tio estas, por kompreni kiom da tempo necesis por efektivigi specifan nodon, aŭ kiom da datumoj ĝuste ĉi tiu legado el la tabelo prenis de la disko, vi devas iel subtrahi unu de la alia - nodtempo bezonata multipliku per bukloj
jes, subtraho ne estas la plej malfacila operacio, kiun oni devas fari "en via kapo" - finfine, la plenumtempo estas indikita kiel mezumo por unu plenumo de nodo, kaj povas esti centoj da ili - Nu, ĉio ĉi kune malhelpas nin respondi la ĉefan demandon - do kiu "la plej malforta ligo"?
Kiam ni provis klarigi ĉion ĉi al plurcent el niaj programistoj, ni rimarkis, ke deekstere ĝi aspektas iel tiel:

Kaj tio signifas, ke ni bezonas...
Ilo
En ĝi, ni provis kolekti ĉiujn ŝlosilajn mekanikojn, kiuj helpas kompreni laŭ la plano kaj peto, "kiu kulpas kaj kion fari." Nu, kaj dividi iom da nia sperto kun la komunumo.
Renkontu kaj ĝuu -
Videbleco de planoj
Ĉu estas facile kompreni planon, kiam ĝi aspektas tiel?
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
Ne vere.
Sed tiel estas, en mallongigita formo, kiam la ŝlosilaj indikiloj estas apartigitaj, ĝi jam estas multe pli klara:

Sed se la plano estas pli komplika, helpo venos cirklodiagrama tempodistribuo per nodoj:

Nu, por la plej malfacilaj opcioj, ĝi venas al la savo ekzekuta diagramo:

Ekzemple, ekzistas tute ne-trivialaj situacioj kiam plano povas havi pli ol unu faktan radikon:


Strukturaj signalvortoj
Nu, se la tuta strukturo de la plano kaj ĝiaj malfortaj punktoj jam estas prezentitaj kaj videblaj, kial ne elstarigi ilin al la programisto kaj klarigi ilin en la "rusa lingvo"?
Ni jam kolektis kelkajn dekduojn da tiaj rekomendŝablonoj.
Lini-post-linia serĉprofililo
Nun, se vi surmetas la originalan serĉmendon al la analizata plano, vi povas vidi kiom da tempo estis elspezita por ĉiu individua operatoro - ion similan al ĉi tio:

... aŭ eĉ tiel:

Anstataŭigante parametrojn en serĉmendon
Se vi alkroĉis al la plano ne nur la serĉmendon, sed ankaŭ ĝiajn parametrojn el la DETALA linio de la protokolo, vi povas kopii ĝin plie en unu el la opcioj:
- kun anstataŭigo de valoroj en la serĉmendon
por rekta efektivigo sur via propra bazo kaj plia profiladoSELECT 'const', 'param'::text; - kun anstataŭigo de valoroj per PREPARE/EXECUTE
por imiti la laboron de la planilo, kiam la parametra parto povas esti ignorata - ekzemple, dum laborado pri dividitaj tabelojDEALLOCATE ALL; PREPARE q(text) AS SELECT 'const', $1::text; EXECUTE q('param'::text);
Arkivo de planoj
Algluu, analizu, kunhavigu kun kolegoj! Planoj restos en la arkivo, kaj vi povos reveni al ili poste:
Sed se vi ne volas, ke aliaj vidu vian planon, ne forgesu marki la keston "ne publikigu en arkivo".
En la sekvaj artikoloj mi diskutos la defiojn kaj solvojn, kiuj aperas dum analizado de plano.
fonto: www.habr.com
