Ang klasikong tanong na dinadala ng isang developer sa kanyang DBA o isang may-ari ng negosyo sa isang consultant ng PostgreSQL ay halos palaging pareho ang tunog: "Bakit napakatagal bago makumpleto ang mga kahilingan sa database?"
Tradisyonal na hanay ng mga dahilan:
- hindi mahusay na algorithm
kapag nagpasya kang SUMALI sa ilang CTE sa loob ng ilang sampu-sampung libong talaan - hindi nauugnay na istatistika
kung ang aktwal na distribusyon ng data sa talahanayan ay ibang-iba na sa nakolekta ng ANALYZE noong nakaraang panahon - "plug" sa mga mapagkukunan
at wala nang sapat na dedikadong computing power ng CPU, ang mga gigabytes ng memorya ay patuloy na ipinobomba, o ang disk ay hindi makakasabay sa lahat ng "gusto" ng database - hinaharang mula sa mga prosesong nakikipagkumpitensya
At kung ang mga pagharang ay medyo mahirap hulihin at pag-aralan, kung gayon para sa lahat ng iba pang kailangan namin plano ng pagtatanong, na maaaring makuha gamit ang
Ngunit, tulad ng nakasaad sa parehong dokumentasyon,
"Ang pag-unawa sa isang plano ay isang sining, at upang makabisado ito ay nangangailangan ng isang tiyak na dami ng karanasan..."
Ngunit magagawa mo nang wala ito kung gagamitin mo ang tamang tool!
Ano ang karaniwang hitsura ng isang query plan? Isang bagay na tulad nito:
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
o ganito:
"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"
Ngunit ang pagbabasa ng plano sa teksto "mula sa sheet" ay napakahirap at hindi malinaw:
- ay ipinapakita sa node kabuuan ng mga mapagkukunan ng subtree
iyon ay, upang maunawaan kung gaano karaming oras ang kinuha upang maisagawa ang isang partikular na node, o kung gaano eksakto ang pagbabasa na ito mula sa talahanayan ay nagdala ng data mula sa disk, kailangan mong ibawas ang isa mula sa isa pa. - kailangan ng oras ng node multiply sa pamamagitan ng mga loop
oo, ang pagbabawas ay hindi ang pinaka kumplikadong operasyon na kailangang gawin "sa ulo" - pagkatapos ng lahat, ang oras ng pagpapatupad ay ipinahiwatig bilang average para sa isang pagpapatupad ng isang node, at maaaring magkaroon ng daan-daang mga ito - mabuti, at ang lahat ng ito nang magkakasama ay pumipigil sa amin na sagutin ang pangunahing tanong - kaya sino "ang pinakamahina na link"?
Nang sinubukan naming ipaliwanag ang lahat ng ito sa ilang daang aming mga developer, napagtanto namin na mula sa labas ay ganito ang hitsura nito:
At ibig sabihin, kailangan natin...
Kasangkapan
Sa loob nito sinubukan naming kolektahin ang lahat ng mga pangunahing mekanika na makakatulong sa pag-unawa sa "sino ang dapat sisihin at kung ano ang gagawin" ayon sa plano at kahilingan. Well, at ibahagi ang bahagi ng iyong karanasan sa komunidad.
Kilalanin at gamitin -
Visibility ng mga plano
Madali bang intindihin ang plano kapag ganito ang hitsura?
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
Hindi talaga.
Ngunit tulad nito, sa pinaikling anyokapag ang mga pangunahing tagapagpahiwatig ay pinaghiwalay, ito ay mas malinaw:
Ngunit kung ang plano ay mas kumplikado, siya ay darating upang iligtas pamamahagi ng oras ng piechart sa pamamagitan ng mga node:
Buweno, para sa pinakamahirap na mga pagpipilian ay nagmamadali siyang tumulong tsart ng pag-unlad:
Halimbawa, may mga hindi mahalaga na sitwasyon kapag ang isang plano ay maaaring magkaroon ng higit sa isang aktwal na ugat:
Mga pahiwatig sa istruktura
Buweno, kung ang buong istraktura ng plano at ang mga masakit na lugar nito ay inilatag at nakikita na, bakit hindi i-highlight ang mga ito sa developer at ipaliwanag ang mga ito sa "wika ng Ruso"?
Nakakolekta na kami ng ilang dosenang mga template ng rekomendasyon.
Line-by-line na query profiler
Ngayon, kung ipapatong mo ang orihinal na query sa nasuri na plano, makikita mo kung gaano katagal ang ginugol sa bawat indibidwal na pahayag - tulad nito:
...o kahit ganito:
Pagpapalit ng mga parameter sa isang kahilingan
Kung "naka-attach" ka hindi lamang ng isang kahilingan sa plano, kundi pati na rin ang mga parameter nito mula sa DETAIL na linya ng log, maaari mo itong kopyahin sa isa sa mga opsyon:
- na may pagpapalit ng halaga sa kahilingan
para sa direktang pagpapatupad sa iyong base at karagdagang pag-profileSELECT 'const', 'param'::text;
- na may pagpapalit ng halaga sa pamamagitan ng PREPARE/EXECUTE
upang tularan ang gawain ng scheduler, kapag ang parametric na bahagi ay maaaring balewalain - halimbawa, kapag nagtatrabaho sa mga partitioned tableDEALLOCATE ALL; PREPARE q(text) AS SELECT 'const', $1::text; EXECUTE q('param'::text);
Archive ng mga plano
I-paste, pag-aralan, ibahagi sa mga kasamahan! Ang mga plano ay mananatiling naka-archive at maaari kang bumalik sa kanila sa ibang pagkakataon:
Ngunit kung ayaw mong makita ng iba ang iyong plano, huwag kalimutang lagyan ng tsek ang kahon na "huwag i-publish sa archive".
Sa mga susunod na artikulo ay pag-uusapan ko ang tungkol sa mga kahirapan at desisyon na lalabas kapag nagsusuri ng isang plano.
Pinagmulan: www.habr.com