Yavaş Database Sorguları Bulma: Net Query Optimizasyon Rehberi
Yavaş sorguları bulup süreyi düşürün: slow query analizi, EXPLAIN, indeks ve yedekli ölçüm planı ile net teşhis adımları.
Database query optimizasyonu, hosting performansını doğrudan etkileyen bir konudur. Yavaş sorgu, yalnızca veritabanını yavaşlatmaz; web isteklerini geciktirir, CPU’yu artırır ve zaman zaman “rastgele” gibi görünen sayfa yavaşlıklarına yol açar. Bu rehberde, yavaş sorguları sistematik biçimde bulmayı, hangi ölçümü hangi sırayla yapacağınızı ve hangi SQL/indeks adımlarının gerçekten işe yaradığını net bir akışla anlatıyorum. Hedefiniz, problemi tahminle değil ölçümle yakalamak.
Aşağıdaki adımlar özellikle MySQL/MariaDB ve PostgreSQL gibi ilişkisel veritabanlarında çalışır. Nerede olursanız olun (VPS, VDS ya da dedicated), aynı mantık geçerlidir: önce “hangi sorgu”, sonra “neden”, en son “nasıl hızlı hale getireceğiz”.
1) Önce hedefi daraltın: “Yavaş” ne demek?
Yavaş sorgu, tek bir süreye göre tanımlanamaz; uygulamanızın SLA’sı (yanıt süresi hedefi) ve trafik profili belirleyicidir.
Pratik hedef tanımı (örnek)
- Uygulama sayfa yanıtı hedefiniz 1 saniye ise: veritabanı payınız genelde 200–400 ms aralığında kalmalıdır.
- Gün içinde bazı saatlerde yük artıyorsa: “ortalama” değil, p95 (95. persentil) gecikmeyi baz alın.
Hızlı tanılama için ölçüm noktaları
- Uygulama tarafı: loglarda SQL süresi (özellikle ORM kullanıyorsanız)
- DB tarafı: slow query log (yavaş sorgu kaydı) / query statistics
- Sistem tarafı: DB CPU, disk I/O, bağlantı sayısı
Bu üçlü birlikte bakılmadığında “yavaş sorgu” ile “kaynak darboğazı” birbirine karışır.
2) MySQL/MariaDB: Slow Query Log ile yavaş sorguları bulun
MySQL/MariaDB’de en hızlı başlangıç noktası slow query log’dur. Bu kayıt, eşik üzerindeki sorguları zaman damgası, kullanıcı, süre ve bazen istatistiklerle saklar.
Ayarları netleştirin
Aşağıdaki mantık önemlidir: - Eşik (long_query_time) çok yüksek olursa gerçek sorunlar kaçırılır. - Çok düşük yaparsanız log şişer, disk doldurma riski oluşur.
Önerilen başlangıç: - long_query_time: 0.5 (0.5 saniye) - log_output: dosya (file) - log_queries_not_using_indexes: ON (indeks kullanılmayan sorguları yakalamak için) - min_examined_row_limit: 0 (yüksek değil düşük başlamak için)
Slow log’u analiz edin: hangi sorgular kritik?
Sadece “en yavaş 10 sorgu”yu görmek yerine şu soruları yanıtlayın: - En çok zaman harcayan sorgu hangisi? (total_time) - Aynı sorgu gün içinde farklı saatlerde mi boğuyor? - İndeks kullanılmayan sorgu oranı yüksek mi? - Lock wait mi var? (varsa başka başlık açılır)
Aşağıdaki tablo yaklaşımı işinizi kolaylaştırır:
| Soru | Kanıt | Öncelik |
|---|---|---|
| En çok toplam süreyi kim harcıyor? | slow log total_time / sık tekrar | En yüksek |
| Aynı sorgu farklı parametrelerle mi yavaş? | query fingerprint benzerliği | Yüksek |
| İndeks kullanılmıyor mu? | log_queries_not_using_indexes | En yüksek |
| Yavaş sorgu tek sefer mi? | kısa süreli spike | Orta |
| Yavaşlık lock ile ilişkili mi? | transaction/lock log | En yüksek |
“Sorgu tekrarı” ve fingerprint
ORM kullanan uygulamalarda sorgu metni farklı görünebilir. Bu yüzden sorguları normalize edip “query fingerprint” ile gruplamak gerekir. Örneğin WHERE id = ? varyasyonları aynı planı kullanabilir.
3) PostgreSQL: pg_stat_statements ile en kötü adayları seçin
PostgreSQL’de slow query log kadar etkili yöntem pg_stat_statements’tır. Bu modül, sorguları istatistiklerle birleştirir.
Net kontrol listesi
- pg_stat_statements aktif mi?
- Statları hangi süre penceresinde izliyorsunuz? (son 30 dakika / 24 saat)
Sonra şu sıralama ile gidin: 1. total_time en yüksek sorgular 2. calls çok olan ama orta süreli sorgular (genelde toplamda büyür) 3. mean_time yüksek olan sorgular
Önemli nokta: total_time ve calls birlikte okunmalıdır. Örneğin tek sefer 10 saniye süren sorgu ile saniyede 50 kez 100 ms süren sorgu farklı önceliklere sahiptir.
4) “Yavaş sorgu” neden yavaş? EXPLAIN ile kök nedeni yakalayın
Sorguyu bulduktan sonra gerçek optimizasyon EXPLAIN ile başlar. EXPLAIN (ve bazı sistemlerde EXPLAIN ANALYZE) bize şu sinyalleri verir: - İndeks mi kullanılıyor, yoksa full scan mi? - Join sırası/planı nasıl? - Tahmin (estimate) ile gerçek (actual) uyuşuyor mu? - Sort/temporary table oluşuyor mu?
MySQL/MariaDB
EXPLAINveyaEXPLAIN ANALYZEkullanın.- Özellikle şunlara bakın:
- type:
ALL(tam tarama) - possible_keys / key: boş mu?
- rows: tahmin edilen satır sayısı aşırı yüksek mi?
- Extra:
Using temporary,Using filesortgibi ibareler var mı?
PostgreSQL
EXPLAIN (ANALYZE, BUFFERS)kullanmak daha net sonuç verir.- Dikkat edilmesi gerekenler:
- Seq Scan var mı?
- Hash Join / Nested Loop hangisi? Ölçekle uyumlu mu?
- “Rows removed by filter” çok mu?
5) Net aksiyon: İndeks, sorgu yazımı ve veri türü uyumu
EXPLAIN size “nereye bakmanız gerektiğini” söyleyince, aksiyon adımlarını şu sırayla yapın. Bu sıra gereksiz değişiklik riskini düşürür.
5.1 İndeks: Doğru indeks, doğru filtre
İndeks eklemek her zaman doğru değildir; yanlış indeks maliyeti artırabilir.
Net indeks stratejisi: - WHERE koşulundaki kolonlar hedeflenir. - Join kolonları indekslenir. - Sort/ORDER BY ve grouping kolonları gerekiyorsa desteklenir.
Örnek (mantık):
- WHERE user_id = ? AND created_at >= ? gibi bir kalıp varsa, çoğu durumda (user_id, created_at) yönlü bileşik indeks daha anlamlı olur.
- Sadece created_at indekslemek, user_id seçiciliği yüksekse yetersiz kalır.
5.2 Sorgu yazımı: Fonksiyonla kolon sarmalama
Şu hata kalıbı çok sık görülür:
- WHERE DATE(created_at) = '2026-10-15'
Bu durumda DB çoğu zaman indeks kullanamaz. Net çözüm:
- Aralık mantığı: created_at >= ... AND created_at < ...
5.3 Veri türü uyumu: CAST ile plan bozulur
Sorguda kolonla parametre tipi uyumsuz olduğunda DB otomatik dönüşüm yapabilir.
- Örneğin varchar kolon üzerinde sayısal karşılaştırma
- UUID metin olarak gelince
Net çözüm: uygulama katmanında doğru tipi gönderin veya şemada uyumu sağlayın.
5.4 Join stratejisi: gereksiz join ve aşırı satır çekme
Yavaş sorguların bir kısmı indeks yerine “fazla veri çekme” yüzündendir. - Gereksiz join’leri kaldırın. - Sadece gereken kolonları seçin (SELECT * yerine) - Limit/pagination doğru mu?
6) Yavaş sorguları bulmayı kalıcı hale getirin: ölçüm, eşik ve regresyon planı
Optimizasyon tek seferlik değildir. Güncelleme, veri büyümesi ve indeks değişiklikleri planı zamanla etkileyebilir.
6.1 Eşik tabanlı izleme
Sadece “şu sorgu yavaş” demeyin. Eşik belirleyin: - 0.5 sn üzeri sorgular slow log’a yazılsın - Toplamda en fazla 20 aday sorgu için günlük liste oluşturulsun
6.2 Regresyon testi
İndeks ekledikten sonra şu kontrolü yapın: - Aynı sorgu için EXPLAIN planı değişti mi? (Seq Scan->Index Scan gibi) - Uygulamada ilgili endpoint’lerin p95 süresi düştü mü? - Yazma (INSERT/UPDATE) performansı kötüleşti mi?
İndeks eklemek okuma hızını artırabilir, yazma hızını düşürebilir. Bu yüzden “sadece SELECT” ölçmek yetmez.
6.3 Kaynak darboğazını elemek: CPU, disk ve bağlantı
Yavaş sorgu raporu gerçek sebep değilse şu kontrolleri ekleyin: - DB CPU %100’e yaklaşıyor mu? - Disk I/O gecikmesi var mı? (özellikle küçük RAM + yoğun sort/temporary) - Bağlantı sayısı aşırı mı? (connection pool ayarı)
Aşağıdaki tablo, “sorgu optimizasyonu mu yoksa altyapı mı?” ayrımında yol gösterir:
| Belirti | Büyük ihtimalle neden | Sonraki adım |
|---|---|---|
| Slow log var ama EXPLAIN indeks gösteriyor | kilit/lock veya kaynak darboğazı | lock/transaction incele |
| EXPLAIN full scan ve rows çok yüksek | indeks eksikliği | uygun indeks ekle |
| İndeks var ama hâlâ sort/temporary oluşuyor | ORDER BY / GROUP BY desteklenmemiş | kompozit indeks veya sorgu değişimi |
| Aynı sorgu hızlı ama p95 yüksek | bağlantı/pool/queue | uygulama ve DB bağlantı trafiği |
7) “En sık yapılan hatalar” listesi (sorunu uzatır)
- Sadece süreye bakıp “calls” değerini atlamak: sık çağrılan orta sorgular en büyük maliyeti çıkarır.
- Eşik ayarını rastgele seçmek: çok yüksek → sorun görünmez; çok düşük → log şişer.
- İndeks ekleyip plan değişmediğini kontrol etmemek: EXPLAIN ile doğrulama şart.
- İndeks eklemeyi sorgu bazında değil “liste halinde” yapmak: rastgele indeksler yazmayı yavaşlatır.
- Regresyon yapmamak: optimize ettiğiniz sorgu iyileşirken başka sorgu kötüleşebilir.
Sonuç: Aksiyon sırası ile ilerleyin
Yavaş sorguları bulmanın doğru yolu “tek seferlik inceleme” değil, ölçüme dayalı bir iş akışıdır. Önce slow query kayıtları (MySQL/MariaDB) veya pg_stat_statements (PostgreSQL) ile aday sorguları listeleyin; sonra EXPLAIN ile kök nedeni belirleyin; en son indeks/sorgu yazımı değişikliklerini uygulayın ve regresyon testinde p95/total_time ile sonucu doğrulayın. Bu akışı NetKıyas tarafındaki sunucu ve performans kararlarınızla da birlikte düşünün: doğru sorgu optimizasyonu, aynı donanımda daha yüksek kapasite anlamına gelir.
Eğer hedefiniz 30 gün içinde somut bir iyileşme ise bugün şu aksiyonları sırayla alın: 1) slow log/pg_stat_statements penceresini açın, 2) en kötü 10 sorguyu çıkarın, 3) her birinin EXPLAIN planını kaydedin, 4) yalnızca planı değiştiren indeks/sorgu iyileştirmelerini devreye alın, 5) p95 regresyon kontrolünü aynı metrikle yapın.
Hosting karşılaştırması yapmaya hazır mısın?
100+ firmanın fiyatlarını tek tıkla karşılaştır, en uygun paketi bul.
Hosting Karşılaştır →İlgili Yazılar
%99.9 uptime garantisi ne kadar gerçekçi? Hesap + kontrol rehberi
%99.9 uptime garantisi yılda ~8 saat kesinti demektir. Ancak ölçüm yöntemi, bakım pencereleri ve kapsam dışı durumlar sonucu değiştirir.
WordPress eklentileri sunucuyu yavaşlatıyorsa: Net tespit & çözüm
WordPress’te eklentiler performansı düşürüyorsa doğru teşhis süreci, ölçüm yöntemleri ve net optimizasyon adımlarını öğrenin.
Reseller Hosting ile İlk Müşteriye Satış: Adım Adım Süreç
Reseller hosting’de ilk müşteri kazanmak için teklif, kurgu, kurulum, SLA ve satış sonrası adımları net bir süreçle öğrenin.
Çoklu WordPress Sitesi (Multisite) için Hosting Rehberi
Multisite (WordPress Multisite) için doğru hosting tipini seçin: kaynak planlama, cache, yedekleme ve güvenlik ayarlarıyla net karar rehberi.
