De klassike fraach dy't in ûntwikkelder nei syn DBA bringt as in bedriuwseigner bringt nei in PostgreSQL-konsultant klinkt hast altyd itselde: "Wêrom nimme fersiken sa lang om te foltôgjen op 'e databank?"
Tradisjoneel set fan redenen:
- inefficiënt algoritme
as jo beslute om mei te dwaan oan ferskate CTE's oer in pear tsientûzenen records - irrelevante statistiken
as de eigentlike ferdieling fan gegevens yn 'e tabel is al hiel oars as de iene sammele troch ANALYZE lêste kear - "plug" op boarnen
en d'r is net mear genôch tawijd komputerkrêft fan 'e CPU, gigabytes oan ûnthâld wurde konstant pompt, of de skiif kin net byhâlde mei alle "wollen" fan 'e databank - blokkearjen út konkurrearjende prosessen
En as blokken frijwat lestich binne om te fangen en te analysearjen, dan foar al it oare dat wy nedich binne query plan, dat kin wurde krigen mei help fan
Mar, lykas sein yn deselde dokumintaasje,
"It begripen fan in plan is in keunst, en om it te behearskjen fereasket in bepaalde hoemannichte ûnderfining ..."
Mar jo kinne sûnder it dwaan as jo it juste ark brûke!
Hoe sjocht in queryplan gewoanlik út? Soksawat:
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
of sa:
"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"
Mar it lêzen fan it plan yn tekst "fan it blêd" is heul lestich en ûndúdlik:
- wurdt werjûn yn it knooppunt som troch subtree boarnen
dat is, om te begripen hoefolle tiid it duorre om in bepaald knooppunt út te fieren, of hoefolle krekt dizze lêzing fan 'e tabel gegevens fan' e skiif brocht hat, moatte jo ien of oare manier fan 'e oare ôflûke - node tiid is nedich fermannichfâldigje troch loops
ja, subtraksje is net de meast komplekse operaasje dy't "yn 'e holle" dien wurde moat - ommers, de útfieringstiid wurdt oanjûn as it gemiddelde foar ien útfiering fan in knooppunt, en d'r kinne hûnderten fan wêze - goed, en dit alles tegearre foarkomt ús út in antwurd op de wichtichste fraach - dus wa "de swakste skeakel"?
Doe't wy dit alles besochten te ferklearjen oan ferskate hûnderten fan ús ûntwikkelders, realisearren wy dat fan bûten it sa útseach:
En dat betsjut dat wy nedich binne ...
Tool
Dêryn hawwe wy besocht alle wichtige meganika te sammeljen dy't helpe te begripen "wa't de skuld is en wat te dwaan" neffens it plan en fersyk. No, en diel in diel fan jo ûnderfining mei de mienskip.
Moetsje en brûke -
Sichtberens fan plannen
Is it maklik om it plan te begripen as it der sa útsjocht?
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 echt.
Mar sa, yn ôfkoarte foarmas de kaai yndikatoaren wurde skieden, it is folle dúdliker:
Mar as it plan yngewikkelder is, komt er te rêden piechart tiid ferdieling troch knooppunten:
No, foar de dreechste opsjes is hy haast om te helpen foarútgong chart:
D'r binne bygelyks frij net-triviale situaasjes as in plan mear as ien wirklike root kin hawwe:
Strukturele oanwizings
No, as de hiele struktuer fan it plan en har seare plakken al oanlein en sichtber binne, wêrom net markearje se oan de ûntwikkelder en ferklearje se yn "Russyske taal"?
Wy hawwe al in pear tsientallen sokke oanbefellingssjabloanen sammele.
Line-by-line query profiler
No, as jo de orizjinele fraach oer it analysearre plan pleatse, kinne jo sjen hoefolle tiid is bestege oan elke yndividuele ferklearring - soksawat as dit:
... of sels sa:
It ferfangen fan parameters yn in fersyk
As jo net allinich in fersyk "taheakke" oan it plan, mar ek syn parameters fan 'e DETAIL-line fan it logboek, kinne jo it ek kopiearje yn ien fan' e opsjes:
- mei weardeferfanging yn 'e query
foar direkte útfiering op jo basis en fierdere profilearringSELECT 'const', 'param'::text;
- mei wearde ferfanging fia PREPARE / EXECUTE
om it wurk fan 'e planner te emulearjen, as it parametryske diel kin wurde negeare - bygelyks by it wurkjen oan partisjonele tabellenDEALLOCATE ALL; PREPARE q(text) AS SELECT 'const', $1::text; EXECUTE q('param'::text);
Argyf fan plannen
Plak, analysearje, diel mei kollega's! De plannen bliuwe argivearre en jo kinne letter weromkomme:
Mar as jo net wolle dat oaren jo plan sjogge, ferjit dan net it fakje "net publisearje yn argyf" te kontrolearjen.
Yn 'e folgjende artikels sil ik prate oer de swierrichheden en besluten dy't ûntsteane by it analysearjen fan in plan.
Boarne: www.habr.com