Örnek sorular
Performance TuningZorluk 1
Yoğun uygulamalar neden her istek için yeni bir bağlantı açmak yerine bir database connection pool'u açık tutup bağlantıları yeniden kullanır?
- aHer seferinde bağlantı kurmak pahalıdır (TCP setup, authentication, sunucu tarafında yeni bir backend), bu yüzden yeniden kullanım bu işi ortadan kaldırır✓
- bPool'daki tek bir bağlantı ağ trafiğini şifreleyebilir, ayrı bağlantılar ise her zaman düz metin olarak gider
- cPool tek bir sorguyu birçok bağlantıya bölerek tek bir yavaş sorgunun kat kat hızlı bitmesini sağlar
- dDatabase aynı bağlantıda birden fazla sorgu çalıştırmayı reddeder, bu yüzden pool olmadan çoğu sorgu başarısız olur
Açıklama:Bağlantı açmak TCP handshake, authentication ve sunucu tarafında bir process/thread ayırmayı içerir — basit bir sorguyu gölgede bırakan onlarca milisaniye. Pool sıcak bağlantıları tutup dağıtır, bu maliyet bir kez ödenir. Pooling tek bir sorguyu paralelleştirmez (c) ve şifrelemeyle ilgisizdir (b).
Performance TuningZorluk 2
Yük altındaki bir servis 'too many connections' hatalarıyla düşmeye başlıyor; oysa database sunucusunun CPU ve disk'i neredeyse boşta. Her istek kendi doğrudan bağlantısını açıyor. En uygun çözüm nedir?
- aUygulama sunucularında işletim sisteminin file-descriptor limitini çok yüksek bir değere çıkarıp bağlantı açmaya devam etmek
- bHer sorguyu SELECT * yaparak database'in her bir statement'ı planlamaya daha az zaman harcamasını sağlamak
- cDatabase'in önüne bir connection pool koymak ve eşzamanlı bağlantı sayısını makul bir değerle sınırlamak✓
- dDatabase kullanıcısına superuser yetkisi vererek bağlantılarının limite sayılmamasını sağlamak
Açıklama:Her backend bağlantısı bellek ve bir sunucu process'i tüketir; sunucu katı bir max_connections limiti uygular ve istek başına bağlantı açmak bu limiti tüketir. Pool bağlantıları sınırlar ve yeniden kullanır, talebi sunucunun taşıyabileceğine oturtur. Superuser limitten muaf tutmaz (d), SELECT * durumu yalnızca kötüleştirir (b).
Performance TuningZorluk 1
Çoğu ilişkisel database, yakın zamanda kullanılan data page'lerin büyük bir in-memory cache'ini tutar. Bu cache'in temel amacı nedir?
- aDatabase'in kullanıcı hesaplarını ve yetki kurallarını saklamak, böylece authentication'ın hızlı kalmasını sağlamak
- bSık erişilen veriyi RAM'den servis edip disk'ten yapılan yavaş okumaları önlemek✓
- cVerinin dayanıklı bir yedek kopyasını tutup tam bir disk arızasında hayatta kalmasını sağlamak
- dEski data page'leri sıkıştırarak tablonun zamanla disk'te daha az yer kaplamasını sağlamak
Açıklama:Buffer/page cache sıcak data page'leri bellekte tutar; böylece tekrarlı okumalar, kat kat yavaş olan disk'e gitmeden karşılanır. Bu bir dayanıklılık (durability) mekanizması değildir — o iş write-ahead log ve disk dosyalarınındır (c) — veriyi sıkıştırmaz ve auth kurallarını tutmaz.
Performance TuningZorluk 2
Bir rapor sorgusu, database yeniden başladıktan sonra ilk çalıştığında 4 saniye sürüyor; aynı veriyle ve başka değişiklik olmadan sonraki birkaç çalıştırmada yalnızca 80 ms. Bunu en olası açıklayan nedir?
- aQuery planner, sorguyu bir kez çalışırken gördükten sonra onu daha hızlı bir forma yeniden yazdı
- bİlk çalıştırma, herhangi bir satır dönmeden önce tablonun tüm index'lerini sıfırdan yeniden kurmak zorunda kaldı
- cDatabase, ilk çalıştırmadan sonra SQL metnini native makine koduna derledi
- dİlk çalıştırma data page'leri disk'ten memory cache'e okudu; sonraki çalıştırmalar bunları zaten cache'de buldu✓
Açıklama:Soğuk cache'te ilk çalıştırma, gereken page'leri buffer cache'e almak için fiziksel disk okumalarını öder; sonraki çalıştırmalar bu page'lere RAM'de erişip disk'i atlar. Burada değişen şey plan ya da derlenmiş statement değildir; okuma sırasında index'ler yeniden kurulmaz (b).
Performance TuningZorluk 1
Tipik bir database iş yükünde, hangi kaynak çoğu zaman birincil performans darboğazıdır?
- aDisk I/O — data page'leri okuyup yazmak, zaten bellekte olan veri üzerinde işlem yapmaktan çok daha yavaştır✓
- bKullanılabilir RAM miktarı, çünkü working set'i belleğe sığan bir sorgu asla yavaşlayamaz
- cCPU saat hızı, çünkü her sorgu neredeyse her zaman I/O-bound değil CPU-bound'dur
- dŞemadaki toplam tablo sayısı, çünkü motor her sorguda her tablonun header'ını taramak zorundadır
Açıklama:Database'ler CPU register'larına sığandan çok daha fazla veriyle çalışır ve disk (SSD dahi olsa) RAM'den kat kat yavaştır; bu yüzden genelde I/O baskındır. Sıcak veriyi bellekte cache'lemenin önemi tam da budur. Çoğu OLTP sorgusu CPU-bound değil I/O-bound'dur (c), tablo sayısı darboğaz değildir (d).
Performance TuningZorluk 2
Bir import işlemi 10.000 satırı, her biri kendi ağ çağrısında olmak üzere 10.000 ayrı INSERT INTO t (...) VALUES (...) statement'ı göndererek yüklüyor. Toplam süreyi en doğrudan hangi değişiklik azaltır?
- aHedef tabloya birkaç index daha ekleyerek her bir INSERT'in disk'e daha hızlı yazılmasını sağlamak
- bKolonları daha kısa adlarla yeniden adlandırıp her INSERT statement'ının parse edilmesini biraz küçültmek
- cSatırları çok-satırlı INSERT'lerde (ya da tek bir bulk statement'ta) gruplayarak çok daha az round trip yapmak✓
- dHer bir INSERT'i kendi ayrı transaction'ına sararak herhangi bir tek hatayı izole etmek
Açıklama:Buradaki baskın maliyet 10.000 ağ round trip'i ve statement başına parse'tır. Çok satırı tek INSERT'te (ya da bir bulk-load komutunda) gruplamak bu round trip'leri bir avuca indirir. Index eklemek her INSERT'i hızlandırmaz yavaşlatır (a); satır başına transaction commit maliyeti ekler (d).