Yavaş Database Query’leri Bulma: MySQL ve PostgreSQL Rehberi
Yavaş sorguları hızlıca tespit etmek için EXPLAIN, slow query log, performans şemaları ve net kontrol adımları: MySQL & PostgreSQL.
Veritabanı yavaşlaması çoğu zaman uygulama katmanından sanılır; oysa geciken isteklerin büyük kısmı, çalışırken bekleyen sorgulardan (query plan) kaynaklanır. Bu rehberde amaç, yavaş query’leri saniyeler içinde bulup kök nedeni netleştirmektir. MySQL ve PostgreSQL için tanılama yöntemlerini (EXPLAIN, slow query log, indeks kontrolü, istatistik/konfigürasyon) somut adımlarla anlattık.
Aşağıdaki süreç; önce “kim yavaş?”, sonra “neden yavaş?”, en sonda da “nasıl düzeltirim?” sorularını sırayla yanıtlamanı sağlar.
1) Önce “yavaş sorgu”yu tanımlayın: hedef ölçüm nedir?
Yavaşlığın tanımı net olmazsa, teşhis de sonuç vermez. En pratik yaklaşım, her veritabanında iki ölçümü aynı anda takip etmektir:
- Uygulama tarafı: Ortalama ve p95 gecikme (response time) + hata oranı
- Veritabanı tarafı: Sorgu başına çalışma süresi (execution time) + bekleme süresi (lock/wait)
Özellikle hosting ortamında en sık karışan durum şudur: Sorgu “çalışıyor gibi” görünür ama aslında kilit (lock) bekler. Bu yüzden “sadece duration” yerine, lock/timeout sinyallerini de kontrol edin.
MySQL için net hedefler
slow_query_log(yavaş sorgu günlüğü) aktif olmalı.- “Slow” eşiğini başlangıçta 1-2 saniye yapın; sistem yüklenmesin.
long_query_timedeğerini güncelleyin (ör. 1s).
PostgreSQL için net hedefler
log_min_duration_statementile belirtilen süreden uzun sorgular log’a düşsün.- Başlangıç için 1000ms (1s) mantıklıdır.
2) MySQL’de yavaş sorguları bulma: slow query log + EXPLAIN
MySQL tarafında yavaş sorguyu bulmanın en hızlı yolu slow query log kullanmaktır. Ardından her şüpheli sorgu için EXPLAIN ile sorgu planını okursunuz.
Adım adım: slow query log açma
Aşağıdaki değerler, paylaşımlı hostingde çoğu zaman yönetici panelinden veya destek talebiyle değiştirilebilir. VDS/VPS’de genelde doğrudan konfigürasyon yapılır.
slow_query_log = 1long_query_time = 1(1 saniye)- Zamanla 2-5 saniyeye çekmek, log hacmini azaltır.
Log’dan “en pahalı” sorguyu seçin
Slow log tek tek satırlar üretir. Bu nedenle filtreleme yapın:
- Aynı query’nin tekrar eden varyasyonlarını gruplayın (farklı parametreler olsa bile gövde aynı olabilir).
- En çok tekrar eden query + en yüksek süreli query birlikte ele alınmalıdır.
Kısa kontrol: Eğer sorgu “çok kez çalışıyor” ama tekil olarak hızlıysa (örn. 50ms), asıl sorun indeks/plan değil, uygulama çağırma sıklığı olabilir.
EXPLAIN ile kök nedeni bulun
Şüpheli query için:
typealanı (ALL, index, range, ref vs.) önemlidir.rowstahmini, ne kadar veri tarandığını düşündürür.keyboşsa (veya beklenen index kullanılmıyorsa) indeks sorunu vardır.Extrabölümünde “Using temporary”, “Using filesort” gibi ifadeler varsa, maliyet artar.
Pratik okuma kılavuzu
type = ALL→ tam tablo taraması riskiUsing filesort→ ORDER BY maliyetliUsing temporary→ GROUP BY / DISTINCT / bazı planlarda ek maliyetkeyboş → doğru index yok ya da kullanılmıyor
Hızlı düzeltme örnekleri (MySQL)
1) WHERE koşulu indekslemiyor
- WHERE alanlarıyla aynı sırada (ve mümkünse aynı kolonda) index oluşturun.
2) ORDER BY, indeks sırasıyla uyumsuz
- Çok sık: WHERE ile filtrelenen alan + ardından ORDER BY alanı birleşik index gerektirir.
3) İndeks var ama “yanlış” kullanılıyor
- Fonksiyonla sarmalama: WHERE DATE(created_at) = ... gibi kalıplar index’i etkisizleştirir.
- Çözüm: Aralıkla yazma: created_at >= ? AND created_at < ?
3) PostgreSQL’de yavaş sorguları bulma: pg_stat_statements + EXPLAIN (ANALYZE)
PostgreSQL’de tek tek log satırları yerine, performans istatistikleri daha hızlı teşhis sağlar. En iyi başlangıç noktası pg_stat_statements ve ardından EXPLAIN (ANALYZE, BUFFERS) kullanmaktır.
Adım adım: pg_stat_statements ile “kim yavaş?”
pg_stat_statementsuzantısı etkinleştirilir.- Sonra
pg_stat_statementstablosundan “en çok toplam süre harcayan” sorguları çıkarın.
Önce şu mantıkla bakın:
total_exec_time(toplam çalışma süresi)calls(çağrı sayısı)mean_exec_time(ortalama)
Burada net karar kuralı şöyledir:
- calls çok yüksek ve mean_exec_time makulse → sorgu planı küçük ama geniş ölçekte etkili
- calls düşük ama total_exec_time çok yüksek → tekil ama ağır sorgu
EXPLAIN (ANALYZE, BUFFERS) ile “neden yavaş?”
Sorguyu kopyalayıp çalıştırmadan önce planı okuyun. Ancak teşhiste en net sonuç ANALYZE ile gerçek çalışma istatistiklerini görmektir.
Kontrol edilmesi gereken alanlar:
- Join türleri: Nested Loop, Hash Join, Merge Join
- Satır tahmin doğruluğu: “rows=...” tahmini büyük sapma gösterirse istatistik sorunu olabilir
- Buffers: shared read, shared hit, temp read/written
- temp artıyorsa disk üzerinde geçici alan kullanımı demektir (sort/hash)
PostgreSQL’de en yaygın kök nedenler
- Yetersiz indeks: özellikle join kolonları ve filtre kolonları
- Yanlış join sırası: istatistik/kolon dağılımları güncel değil
- Work_mem düşük: sort/hash işlemleri diske taşabilir
- LIKE/ILIKE veya function-based koşulların planı bozulması
İndeks stratejisi: net kurallar
- Join kolonlarına index:
ON a.customer_id = b.customer_id - WHERE filtre kolonlarına index
- ORDER BY için, mümkünse aynı sırayı takip eden bileşik index
- Sık kullandığınız sorgunun gerçekten “kullandığı” koşulları esas alın (tüm sorguların tek bir index planıyla düzelmesi beklenmez)
4) “Belge gibi” teşhis akışı: yavaş sorguyu 20 dakikada sınıflandırın
Aşağıdaki akış, bir query çıktığında doğru yola girmenizi sağlar. Bu rehberi izleyen bir kişi, tek seferde doğru teşhise yaklaşır.
4.1 Hangi sorgu?
- MySQL: slow log’da en uzun süreli ilk 10
- PostgreSQL: pg_stat_statements’da total_exec_time ilk 10
4.2 Sorgu lock bekliyor mu?
- MySQL’de processlist/lock gözlemi
- PostgreSQL’de
pg_locksve statement timeout/lock wait izleme
Lock wait varsa, çözüm “index eklemek” olmayabilir; transaction süresi, isolation seviyesi veya uygunsuz akış olabilir.
4.3 Sorgu planı tarama yapıyor mu?
- EXPLAIN’de
ALL/tam tarama (MySQL) veya yüksek maliyetli seq scan (PostgreSQL) - Satır tahmini çok büyüyorsa: indeks veya istatistik gerekir
4.4 ORDER BY/GROUP BY geçici alan kullanıyor mu?
- MySQL:
Using temporary,Using filesort - PostgreSQL:
temp read/writtenartışı
4.5 İstatistik güncel mi?
- PostgreSQL:
ANALYZEgerekebilir - MySQL: kullanılan motor ve istatistik yaklaşımına göre indeks seçimi etkilenebilir
5) İndeks ve sorgu revizyonu: düzeltmenin “kanıt” ile yapılması
Yavaş sorgular için en sık yapılan hata, “tahmin ederek index eklemek”tir. Bu yaklaşım, maliyeti düşürmez; bazen yazma performansını (INSERT/UPDATE) ciddi yavaşlatır.
Bu yüzden her değişiklikte şu kuralı uygulayın:
1) Önce planı kaydedin (EXPLAIN sonucu) 2) Değişikliği yapın (index veya sorgu dönüşümü) 3) Tekrar planı karşılaştırın 4) Gecikmeyi ölçün (p95 ve ortalama)
MySQL’de indeks eklemenin net sonuçları
- Okuma hızlanır (SELECT)
- Yazma yavaşlayabilir (INSERT/UPDATE/DELETE)
- Bileşik index sırası önemlidir
Örnek bir mantık:
- WHERE customer_id = ? AND status = ? ORDER BY created_at DESC
- En mantıklı index genellikle: (customer_id, status, created_at) veya sorgu varyantına göre uyumlu bir sıralamadır.
PostgreSQL’de indeks eklemenin net sonuçları
- Doğru index ile seq scan yerine index scan olur
- Join maliyeti düşer
- Ancak yanlış index veya gereksiz indeks, bakım maliyeti getirir
Ayrıca PostgreSQL’de bazen sorgu yeniden yazımı daha etkilidir: - Uygunsuz casting (örn. kolonu text’e çevirme) - Fonksiyonlu koşullar - Gereksiz DISTINCT veya geniş GROUP BY
6) Hosting ortamında pratik kontrol listesi (VDS/VPS dahil)
Yavaş sorgu bulma süreci sadece SQL değildir; sunucu kaynakları ve log/izleme erişimi de belirleyicidir. Aşağıdaki kontrol listesi, NetKıyas üzerinden VDS/VPS seçimi yaparken de aynı mantıkla işe yarar.
- Log erişimi: slow query log / pg_stat_statements görünür olmalı
- Zaman senkronu: uygulama ve DB saatleri uyumlu olmalı (debug süresi kısalır)
- Disk ve IOPS: temp tabloları/sonuç materialization disk’e taşarsa belirgin gecikme görürsünüz
- RAM: sort/hash işlemleri için yeterli bellek yoksa performans düşer
- Connection yönetimi: bağlantı havuzu yoksa DB üzerinde gereksiz yük oluşur
“Ne zaman indeksten önce konfigürasyon bakmalıyım?” net işaretler
- PostgreSQL’de temp kullanımı yüksek:
work_memetkisi kontrol edilir - MySQL’de büyük join’lerde derleme/plan farklılıkları: istatistik ve sorgu yazımı gözden geçirilir
- Her sorgu yavaş: sadece tek query değil, genel kaynak yetersizliği (CPU/RAM/IOPS) ihtimali vardır
Karşılaştırmalı kontrol: MySQL vs PostgreSQL hızlı özet
Aşağıdaki tablo, yavaş query bulma adımlarını iki sistem için netleştirir.
| Adım | MySQL | PostgreSQL |
|---|---|---|
| Yavaş sorgu tespiti | slow query log + long_query_time |
pg_stat_statements + total_exec_time |
| Plan analizi | EXPLAIN |
EXPLAIN (ANALYZE, BUFFERS) |
| İndeks kontrol sinyali | type=ALL, key boş, Using filesort |
seq scan yerine index scan, temp read/write |
| Kök neden sınıflama | tarama mı, sort mu, lock mu | istatistik mi, join mi, temp mi |
Sonuç: Aksiyon planı (hemen uygulanabilir)
Yavaş sorgu bulma işini “tek tek tahmin” yerine kanıtlı bir akışa bağlayın. İlk adım olarak MySQL’de slow query log’u 1 saniye eşiğiyle etkinleştirin; PostgreSQL’de pg_stat_statements ile toplam süre harcayan ilk 10 sorguyu çıkarın. Ardından her şüpheli sorgu için EXPLAIN planını karşılaştırın ve değişiklikten önce/sonra ölçüm yapın (p95 gecikme ve query süresi). Bu yaklaşımı uyguladığınız ilk döngüde, sorgu revizyonu veya indeks düzeltmesiyle gerçek performans kazanımına hızlıca ulaşırsınız.
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
Site Geçici Kapanınca SEO İçin Doğru 503 Kodu Nasıl Kullanılır?
Siteyi geçici kapattığınızda SEO’nun etkilenmemesi için doğru 503 yanıtını, Retry-After ve yönlendirmeyi net örneklerle öğrenin.
Game Server İçin VDS Seçerken 9 Kriter (Net Karşılaştırma)
Game server için VDS seçerken gecikme, CPU, bant genişliği, disk ve yedekleme gibi 9 kritere göre net kontrol listesi ve karşılaştırma.
Browser Cache Nasıl Yapılandırılır? Chrome/Firefox Adım Adım
Browser cache’i doğru ayarla: HTTP header (Cache-Control, ETag) ve tarayıcı ayarlarıyla sayfa hızını artır, gereksiz güncellemeleri azalt.
Domain Privacy Lock Nedir? Neden Her Zaman Açık Olmalı?
Domain Privacy Lock, alan adı kayıt bilgilerinin herkese açık görünmesini engeller. Bu rehberde ne işe yaradığını ve ne zaman açmanız gerektiğini anlatıyoruz.