Yanıtlar:
Explaining_EXPLAIN.pdf de yardımcı olabilir.
Her zaman kafa karıştırıcı bulduğum kısım, başlangıç maliyeti ile toplam maliyettir. Bunu her unuttuğumda Google'da aradım, bu da beni buraya getiriyor, bu farkı açıklamıyor, bu yüzden bu cevabı yazıyorum. Bu benim panoda da budur Postgres EXPLAINbelgelerinde , Anladığım kadarıyla açıkladı.
İşte bir forumu yöneten bir uygulamadan bir örnek:
EXPLAIN SELECT * FROM post LIMIT 50;
Limit (cost=0.00..3.39 rows=50 width=422)
-> Seq Scan on post (cost=0.00..15629.12 rows=230412 width=422)
İşte PgAdmin'in grafik açıklaması:
(PgAdmin'i kullanırken, maliyet ayrıntılarını okumak için farenizi bir bileşenin üzerine getirebilirsiniz.)
Ekonomik maliyeti, örneğin bir demet olarak temsil edilir LIMITolan cost=0.00..3.39ve sırayla tarama maliyeti postolan cost=0.00..15629.12. Demetteki ilk sayı başlangıç maliyetidir ve ikinci sayı toplam maliyettir . Kullandığım EXPLAINve kullanmadığım için EXPLAIN ANALYZE, bu maliyetler gerçek ölçüler değil tahminlerdir.
Bir karmaşıklık olarak, her "ana" düğümün maliyeti, alt düğümlerinin maliyetlerini içerir. Metin temsilinde, ağaç girintiyle temsil edilir, örneğin LIMITbir ana düğümdür ve Seq Scanonun alt öğesidir. PgAdmin gösteriminde, oklar çocuktan ebeveyne işaret eder - veri akışının yönü - bu, grafik teorisine aşina iseniz mantıksız olabilir.
Belgeler, maliyetlerin tüm alt düğümleri kapsadığını söylüyor, ancak ebeveynin toplam maliyetinin, alt düğümün toplam maliyetinden 3.39çok daha düşük olduğuna dikkat edin 15629.12. Toplam maliyet kapsamlı değildir çünkü gibi bir bileşenin LIMITtüm girdisini işlemesi gerekmez. Postgres belgelerindekiEXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; örneğe bakın .EXPLAIN
Yukarıdaki örnekte, başlangıç zamanı her iki bileşen için de sıfırdır, çünkü hiçbir bileşenin satır yazmaya başlamadan önce herhangi bir işlem yapması gerekmez: sıralı bir tarama, tablonun ilk satırını okur ve yayar. LIMITOnun ilk satırı okur ve sonra yayar.
Bir bileşenin herhangi bir satır çıktısını almaya başlayabilmesi için ne zaman çok fazla işlem yapması gerekir? Pek çok olası neden var, ancak net bir örneğe bakalım. İşte öncekinden aynı sorgu, ancak şimdi bir ORDER BYcümle içeriyor :
EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;
Limit (cost=23283.24..23283.37 rows=50 width=422)
-> Sort (cost=23283.24..23859.27 rows=230412 width=422)
Sort Key: body
-> Seq Scan on post (cost=0.00..15629.12 rows=230412 width=422)
Ve grafiksel olarak:
Bir kez daha, sıralı taramanın postbaşlangıç maliyeti yoktur: hemen satırları çıkarmaya başlar. Ancak sıralamanın önemli bir başlangıç maliyeti vardır 23283.24çünkü tek bir satır bile çıktı verebilmesi için tüm tabloyu sıralamak zorundadır . Sıralamanın toplam maliyeti 23859.27, başlangıç maliyetinden yalnızca biraz daha yüksektir, bu da tüm veri kümesi sıralandıktan sonra sıralanan verilerin çok hızlı bir şekilde yayınlanabileceği gerçeğini yansıtır.
Uyarı başlangıç zamanı o LIMIT 23283.24tür başlatma zaman tam olarak eşittir. Bunun nedeni LIMIT, başlangıç süresinin yüksek olması değildir . Aslında kendi başına sıfır başlangıç süresine sahiptir, ancak EXPLAINher ebeveyn için tüm alt maliyetleri toplar, bu nedenle LIMITbaşlangıç süresi, çocuklarının toplam başlangıç sürelerini içerir.
Bu maliyet toplamı, her bir bileşenin yürütme maliyetini anlamayı zorlaştırabilir. Örneğin, LIMITbaşlangıç zamanımız sıfır, ancak bu ilk bakışta açık değil. Bu nedenle, Hubert Lubaczewski (diğer adıyla depesz) tarafından yaratılan ve diğer şeylerin yanı sıra çocuk maliyetlerini ebeveyn maliyetlerinden çıkararak anlamaya yardımcı olan bir araç olan açıklama.depesz.com ile bağlantılı birkaç kişi daha EXPLAIN. Aracıyla ilgili kısa bir blog yazısında diğer bazı karmaşıklıklardan bahsediyor .
En çok girintili ile en az girintili arasında çalışır ve planın en altından en üste doğru inanıyorum. (Dolayısıyla, iki girintili bölüm varsa, sayfanın daha aşağısındaki biri önce çalıştırır, sonra diğeriyle karşılaştıklarında onları birleştiren kural yürütülür.)
Buradaki fikir, her adımda gelen ve bir kural tarafından işlenen 1 veya 2 veri kümesi olmasıdır. Yalnızca bir veri kümesi varsa, bu işlem o veri kümesine yapılır. (Örneğin, hangi satırları istediğinizi bulmak, bir veri kümesini filtrelemek veya sıralamak için bir dizini tarayın.) Eğer iki ise, iki veri kümesi daha fazla girintili olan iki şeydir ve gördüğünüz kuralla birleştirilirler. Kuralların çoğunun anlamı makul ölçüde kolayca tahmin edilebilir (özellikle daha önce bir dizi açıklama planı okuduysanız), ancak tek tek öğeleri belgelere bakarak veya (daha kolay) yalnızca ifadeyi atarak doğrulamayı deneyebilirsiniz. Google gibi birkaç anahtar kelime ile birlikte EXPLAIN.
Açıkçası bu tam bir açıklama değil, ancak genellikle ne istersen bulman için yeterli bağlam sağlıyor. Örneğin bu planı gerçek bir veritabanından düşünün:
explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';
------------------------------------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
Merge Cond: (a.orderid = b.orderid)
-> Sort (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
Sort Key: a.orderid
Sort Method: quicksort Memory: 1695kB
-> Bitmap Heap Scan on orderitemattribute a (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
Recheck Cond: ((attributeid)::text = 'display-album'::text)
-> Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
Index Cond: ((attributeid)::text = 'display-album'::text)
-> Sort (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
Sort Key: b.orderid
Sort Method: quicksort Memory: 76kB
-> Bitmap Heap Scan on orderitem b (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
Recheck Cond: ((productid)::text = 'ModernBook'::text)
-> Bitmap Index Scan on id_orderitem_productid (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
Index Cond: ((productid)::text = 'ModernBook'::text)
Total runtime: 842.134 ms
(17 rows)
Kendiniz için okumayı deneyin ve mantıklı olup olmadığına bakın.
Okuduğum şey, veritabanının önce id_orderitem_productidindeksi taraması, istediği satırları bulmak için bunu orderitemkullanarak, daha sonra bir hızlı sıralama kullanarak bu veri kümesini sıralaması (veriler RAM'e sığmazsa kullanılan sıralama değişecektir) ve ardından bunu bir kenara koymasıdır.
Daha sonra, orditematt_attributeid_idxistediği satırları bulmak için tarar orderitemattributeve ardından bir hızlı sıralama kullanarak bu veri kümesini sıralar.
Daha sonra iki veri kümesini alır ve bunları birleştirir. (Birleştirme birleştirme, sıralı iki veri kümesini paralel olarak yürüterek eşleştiklerinde birleştirilmiş satırı yayan bir tür "sıkıştırma" işlemidir.)
Dediğim gibi, planın iç kısmından dış kısmına, aşağıdan yukarıya doğru çalışıyorsunuz.
Analiz sonuçlarının pahalı kısımlarının nerede olduğunu vurgulayacak olan Depesz adında bir çevrimiçi yardımcı araç da mevcuttur .
ayrıca bir tane var, işte aynı sonuçlar , bana göre sorunun nerede olduğunu daha net hale getiriyor.
PgAdmin size açıklama planının grafiksel bir sunumunu gösterecektir. İkisi arasında gidip gelmek, metin temsilinin ne anlama geldiğini anlamanıza gerçekten yardımcı olabilir. Bununla birlikte, sadece ne yapacağını bilmek istiyorsanız, her zaman GUI'yi kullanabilirsiniz.
PostgreSQL'in resmi belgeleri , açıklamanın çıktısının nasıl anlaşılacağına dair ilginç ve kapsamlı bir açıklama sağlar.