Örnek sorular
Pg Query PlanningZorluk 1
Bir geliştirici bir SELECT sorgusuna EXPLAIN, sonra aynı sorguya EXPLAIN ANALYZE çalıştırıyor. İkisi arasındaki temel fark nedir?
- aEXPLAIN yalnızca tahmini planı gösterir; EXPLAIN ANALYZE sorguyu gerçekten çalıştırır ve gerçek süreleri ekler✓
- bEXPLAIN ANALYZE aynı planı yalnızca daha okunaklı biçimlendirir; ikisi de sorguyu çalıştırmaz
- cEXPLAIN sorguyu çalıştırıp sonuç satırlarını döner, EXPLAIN ANALYZE ise yalnızca tahmini planı gösterir
- dİkisi de sorguyu aynı şekilde çalıştırır; tek fark çıktının JSON mı düz metin mi olduğudur
Açıklama:EXPLAIN planner'dan bir plan ister ve hiçbir şey çalıştırmadan maliyet/satır tahminlerini gösterir. EXPLAIN ANALYZE ise ifadeyi gerçekten çalıştırır, sonra her node'a tahminlerin yanına gerçek geçen süreyi ve gerçek satır sayısını ekler; böylece tahmin ile gerçeği kıyaslayabilirsin. (b) ve (c) buna uymuyor, (d) ise EXPLAIN'in tek başına sorguyu hiç çalıştırmadığını göz ardı ediyor.
Pg Query PlanningZorluk 2
Bir takım arkadaşı UPDATE orders SET status = 'paid' WHERE customer_id = 42; sorgusunun gerçek execution planını görmek istiyor ve canlı veritabanında doğrudan EXPLAIN ANALYZE çalıştırıyor. Gerçekte ne olur?
- aPostgreSQL ifadenin bir yazma olduğunu algılar ve sessizce salt-okunur bir tahmin planına düşürür
- bUPDATE gerçekten çalışır ve her zamanki gibi commit edilir; EXPLAIN ANALYZE bunu kendiliğinden geri almaz✓
- cPostgreSQL sözdizimi hatası verir, çünkü EXPLAIN ANALYZE yalnızca SELECT ifadelerini kabul eder
- dSatırlar EXPLAIN süresince kilitlenir ama tabloya hiçbir yazma asla uygulanmaz
Açıklama:EXPLAIN ANALYZE gerçek zamanlama ve satır sayısı toplamak için ifadeyi gerçekten çalıştırır — UPDATE/DELETE/INSERT için bu, verinin gerçekten değiştiği ve açık bir transaction yoksa hemen commit edildiği anlamına gelir. Salt-okunur değildir (a), DML için geçerli bir sözdizimidir (c), yalnızca kilitleyen bir prova da değildir (d). Bir yazmanın planını güvenle incelemek için BEGIN; ... ROLLBACK; içine sarmalısın.
Pg Query PlanningZorluk 3
Gerçek veri içeren bir tabloda DELETE FROM orders WHERE status = 'cancelled'; için gerçek EXPLAIN ANALYZE planını görmen gerekiyor, ama o satırları kalıcı olarak kaybetmeden. Gerçek çalıştırma: DELETE'ten önce status = 'cancelled' olan 50000 satır vardı; EXPLAIN ANALYZE DELETE ... çalıştıktan hemen sonra 0 oldu; ROLLBACK verilince tekrar 50000'e döndü. Hangi yaklaşım kullanıldı?
- aEXPLAIN ANALYZE yerine yalnızca
EXPLAIN çalıştırmak, çünkü tek başına EXPLAIN veriye hiç dokunmaz - bÖnce tablonun tam yedeğini almak, DELETE'i çalıştırmak, sonra yedeği geri yüklemek
- cBir transaction açıp içinde
EXPLAIN ANALYZE DELETE ... çalıştırmak, sonra COMMIT yerine ROLLBACK vermek✓ - dDELETE'i bir read replica üzerinde çalıştırmak, çünkü replica'larda EXPLAIN ANALYZE yıkıcı olmaz
Açıklama:Bir DELETE üzerinde EXPLAIN ANALYZE satırları gerçekten siler; değişikliği kalıcı hale getirmeden gerçek planı incelemenin tek güvenli yolu BEGIN; EXPLAIN ANALYZE DELETE ...; ROLLBACK;dir — ifade transaction içinde gerçekten çalışır (böylece plan ve süreler gerçektir) ve rollback etkiyi geri alır. (a) gerçek süre/actual rows hiç vermez. (b) işe yarar ama transaction'a kıyasla gereksiz ağır bir dolambaçtır. (d) yanlıştır çünkü bir read replica yazma ifadelerini kabul etmez.
Pg Query PlanningZorluk 1
Seq Scan on orders (cost=0.00..3627.00 rows=200000 width=32) gibi bir EXPLAIN satırında cost=0.00..3627.00 kısmı neyi ifade eder?
- aSorgunun çalışması gerçekte kaç milisaniye sürdüğünün minimum ve maksimum değeri
- bBu node'un sorgunun toplam CPU süresinden yüzde kaç tükettiğinin tahmini
- cBu node için okunacak ve yazılacak tahmini disk bloğu sayısı
- dPlanner'ın başlangıç ve toplam maliyetini gösteren, süre ölçümü olmayan keyfi birimler✓
Açıklama:cost=başlangıç..toplam, planner'ın kendi keyfi maliyet birimleriyle (seq_page_cost/cpu_tuple_cost gibi ayarlardan türetilir) ifade edilir ve yalnızca aday planları birbiriyle kıyaslamak için kullanılır. Asla milisaniye değeri (a), CPU yüzdesi (b) ya da blok okuma/yazma sayısı (c) değildir — bunlar için EXPLAIN ANALYZE ile BUFFERS/gerçek süreler gerekir.
Pg Query PlanningZorluk 2
pgscratch'ten gerçek plan:
Index Scan using orders_pkey on orders (cost=0.42..8.44 rows=1 width=32)
Index Cond: (id = 42)
cost=0.42..8.44 içindeki
0.42 ve
8.44 sayıları sırasıyla neyi ifade eder?
- a8.44 ilk satırı bulma maliyeti, 0.42 ise tüm satırları döndürme maliyetidir
- b0.42 ilk satıra ulaşmanın tahmini maliyeti; 8.44 ise tüm satırların tahmini maliyetidir✓
- c0.42 okunan index sayfası sayısı, 8.44 ise okunan heap sayfası sayısıdır
- d0.42 ANALYZE çalıştırılmadan önceki maliyet, 8.44 ise ANALYZE çalıştırıldıktan sonraki maliyettir
Açıklama:cost=X..Y her zaman başlangıç_maliyeti..toplam_maliyettir: X, node ilk çıktı satırını üretebilmeden önceki tahmini maliyet; Y ise node'un TÜM çıktısını üretmesinin tahmini maliyetidir. Bu tek-satırlık Index Cond arama için iki sayı da doğal olarak küçüktür. (a) sırayı ters çeviriyor, (c) maliyet birimlerini sayfa sayısıyla karıştırıyor, (d) ise cost='ın taşımadığı bir ANALYZE-öncesi/sonrası anlamı uyduruyor.
Pg Query PlanningZorluk 2
200,000 satırlık
orders tablosunda
SELECT * FROM orders WHERE status = 'paid'; için gerçek plan (
status üzerinde
orders_status_idx index'i var):
Bitmap Heap Scan on orders (cost=556.13..2802.22 rows=49527 width=32)
Recheck Cond: (status = 'paid'::text)
-> Bitmap Index Scan on orders_status_idx (cost=0.00..543.75 rows=49527 width=0)
Index Cond: (status = 'paid'::text)
EXPLAIN ANALYZE çalıştırmadan,
Bitmap Heap Scan satırındaki
rows=49527 neyi ifade eder?
- aTablo istatistiklerinden planner'ın tahmini eşleşen satır sayısı — ölçülmüş bir sayı değil✓
- bBu EXPLAIN üretildiğinde eşleşen satırların zaten ölçülmüş, kesin sayısı
- cWHERE koşulundan bağımsız olarak
orders tablosundaki toplam satır sayısı - dPostgreSQL'in örtük bir LIMIT uygulamadan önce döndüreceği maksimum satır sayısı
Açıklama:Düz EXPLAIN (ANALYZE'siz) sorguyu asla çalıştırmaz, bu yüzden her node'daki her rows= değeri — bu dahil — kolon istatistiklerinden (en-sık-değerler, histogram, vb.) türetilen saf bir planner tahminidir, ölçülmüş bir değer değildir. Gerçek, çalıştırılmış satır sayısını görmek için EXPLAIN ANALYZE gerekir; orada actual rows=... olarak görünür. (b) bunu ölçülmüş diye yanlış etiketliyor, (c) tablonun toplam satır sayısıyla (200,000) karıştırıyor, (d) ise sorguda olmayan bir LIMIT uyduruyor.