Déi klassesch Fro, déi en Entwéckler op seng DBA bréngt oder e Geschäftsbesëtzer un e PostgreSQL Beroder bréngt, kléngt bal ëmmer d'selwecht: "Firwat daueren Ufroe sou laang fir op der Datebank ze kompletéieren?"
Traditionell Set vu Grënn:
- ineffizient Algorithmus
wann Dir décidéiert fir e puer CTEs iwwer e puer Zéngdausende vun Opzeechnunge matzemaachen - irrelevant Statistiken
wann déi tatsächlech Verdeelung vun den Donnéeën an der Tabell scho ganz anescht ass wéi déi vun der ANALYZE d'lescht Kéier gesammelt - "Plug" op Ressourcen
an et gëtt net méi genuch engagéiert Rechenkraaft vun der CPU, gigabytes Erënnerung gi stänneg gepompelt, oder d'Disk kann net mat all de "Wënsch" vun der Datebank halen - blockéieren aus konkurréiere Prozesser
A wann d'Blockéierungen zimlech schwéier ze fangen an ze analyséieren, dann fir alles wat mir brauchen Ufro Plang, déi kritt kënne mat
Awer, wéi an der selwechter Dokumentatioun uginn,
"E Plang ze verstoen ass eng Konscht, a fir et ze beherrschen erfuerdert eng gewëssen Erfahrung ..."
Awer Dir kënnt ouni et maachen wann Dir dat richtegt Tool benotzt!
Wéi gesäit en Ufroplang typesch aus? Eppes wei dat:
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
oder esou:
"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"
Awer de Plang am Text "vum Blat" ze liesen ass ganz schwéier an onkloer:
- gëtt am Node ugewisen Zomm vun subtree Ressourcen
dat ass, fir ze verstoen wéi vill Zäit et gedauert huet fir e bestëmmten Node auszeféieren, oder wéi vill genau dës Liesung aus der Tabell Daten vun der Disk bruecht huet, musst Dir iergendwéi een vun deem aneren ofzéien - Node Zäit ass néideg multiplizéieren duerch Schleifen
jo, d'Subtraktioun ass net déi komplexst Operatioun déi "am Kapp" muss gemaach ginn - schliisslech gëtt d'Ausféierungszäit als Moyenne fir eng Ausféierung vun engem Node uginn, an et kënnen Honnerte vun hinnen sinn - gutt, an all dëst zesummen verhënnert datt mir d'Haaptfro beäntweren - also wien "de schwaachste Link"?
Wa mir probéiert hunn dëst alles fir e puer honnert vun eisen Entwéckler z'erklären, hu mir gemierkt datt et vu baussen esou ausgesäit:
An dat heescht mir brauchen ...
Tool
An et hu mir probéiert all d'Schlësselmechanik ze sammelen, déi hëllefen ze verstoen "wien d'Schold ass a wat ze maachen" no dem Plang an Ufro. Gutt, an deelt en Deel vun Ärer Erfahrung mat der Gemeinschaft.
Trefft a benotzt -
Visibilitéit vu Pläng
Ass et einfach de Plang ze verstoen wann et esou ausgesäit?
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
Net wierklech.
Awer esou, a verkierzte Formwann d'Schlësselindikatoren getrennt sinn, ass et vill méi kloer:
Awer wann de Plang méi komplizéiert ass, kënnt hien zur Rettung piechart Zäit Verdeelung duerch Noden:
Gutt, fir déi schwieregste Optiounen ass hien presséiert ze hëllefen Fortschrëtt Diagramm:
Zum Beispill, et ginn zimlech net-trivial Situatiounen, wann e Plang méi wéi eng tatsächlech Wuerzel huet:
Strukturell Hiweiser
Gutt, wann d'ganz Struktur vum Plang a seng Halswéi scho geluecht a sichtbar sinn, firwat se net dem Entwéckler markéieren an se an "Russesch Sprooch" erklären?
Mir hu schonn e puer Dosen esou Empfehlungsschabloune gesammelt.
Line-by-line Query Profiler
Elo, wann Dir déi ursprénglech Ufro op den analyséierten Plang iwwerlagert, kënnt Dir gesinn wéi vill Zäit op all eenzel Ausso verbruecht gouf - sou eppes:
... oder souguer esou:
Ersetzen Parameteren an eng Ufro
Wann Dir net nëmmen eng Ufro un de Plang "befestegt" hutt, awer och seng Parameteren aus der DETAIL Linn vum Logbuch, kënnt Dir et zousätzlech an enger vun den Optiounen kopéieren:
- mat Wäertsubstitutioun an der Ufro
fir direkt Ausféierung op Ärer Basis a weider ProfilerSELECT 'const', 'param'::text;
- mat Wäertsubstitutioun iwwer PREPARE / EXECUTE
fir d'Aarbecht vum Scheduler ze emuléieren, wann de parametreschen Deel ignoréiert ka ginn - zum Beispill wann Dir un partitionéierten Dëscher schafftDEALLOCATE ALL; PREPARE q(text) AS SELECT 'const', $1::text; EXECUTE q('param'::text);
Archiv vun Pläng
Paste, analyséieren, deelen mat Kollegen! D'Pläng bleiwen archivéiert an Dir kënnt spéider op se zréckkommen:
Awer wann Dir net wëllt datt anerer Äre Plang gesinn, vergiesst net d'Këscht "net am Archiv publizéieren" ze kontrolléieren.
An den folgenden Artikelen wäert ech iwwer d'Schwieregkeeten an Entscheedungen schwätzen, déi entstinn wann Dir e Plang analyséiert.
Source: will.com