Veritabanı Optimizasyonu ve Query Tuning | SQL Performans Rehberi

Veritabanı Optimizasyonu ve Query Tuning | SQL Performans Rehberi

Yazar

Ayberk Tığlı

Yayınlanma Tarihi
9 Haziran 2026
Görüntüleme
926

Veritabanı Performansında "O An": Optimizasyon ve Query Tuning Rehberi

Hepimiz o anı yaşamışızdır: Harika bir özellik geliştirirsiniz, her şey yerel sunucuda tıkır tıkır çalışır. Ancak canlıya çıktıktan birkaç hafta sonra, kullanıcı sayısı arttıkça o çok güvendiğiniz sayfa yavaşlamaya, işlemci (CPU) grafikleriniz tavan yapmaya başlar. İşte tam bu noktada "hallederiz ya" dediğimiz veritabanı sorguları, sistemin en büyük darboğazı haline gelir.

Veritabanı optimizasyonu sadece "birkaç indeks ekleyelim geçer" mantığından çok daha fazlasıdır. Bu, uygulamanızın kalbiyle doğru dilde konuşma sanatıdır. Gelin, bir blog yazısı samimiyetinde ama bir kıdemli mühendis derinliğinde bu konuyu masaya yatıralım.

1. Her Şeyin Başı: Execution Plan (Yürütme Planı) Okumak

Bir sorguyu optimize etmeye başlamadan önce, veritabanı motorunun o sorguyu nasıl çalıştırdığını anlamanız gerekir. Veritabanına bir sorgu gönderdiğinizde, arka planda bir "Cost Optimizer" (Maliyet Optimize Edici) devreye girer ve veriye ulaşmak için en ucuz yolu seçer.

  • Explain / Explain Analyze: SQL sorgunuzun başına bu komutu eklediğinizde, veritabanı size bir yol haritası sunar.
  • Seq Scan (Sequential Scan): Eğer bunu görüyorsanız tehlike çanları çalıyor demektir. Veritabanı, aradığınız kaydı bulmak için tüm tabloyu baştan sona okuyordur.
  • Index Scan: İşte görmek istediğimiz bu. Veritabanı, bir sözlüğün fihristini kullanır gibi hedefe doğrudan gidiyordur.

Altın Kural: Tahmin etmeyin, ölçün. Yürütme planını okumadan yapılan her optimizasyon hamlesi, karanlıkta ok atmaya benzer.

2. İndeksleme: Doğru Silahı Seçmek

İndeksler, veritabanı performansının mucizesidir ama yanlış kullanıldığında tam bir ayak bağına dönüşebilirler.

  • B-Tree İndeksler: Genel kullanımın %90'ını kapsar. Eşitlik ve aralık sorgularında ( < , > , BETWEEN ) harikadır.
  • Composite (Bileşik) İndeksler: Birden fazla sütun üzerinden arama yapıyorsanız, sütun sırası kritiktir. Genelde "seçiciliği" (selectivity) en yüksek olan sütunu en başa koymak performansı artırır.
  • İndeks Fazlalığı (Over-Indexing): Unutmayın, her INSERT, UPDATE ve DELETE işlemi, ilgili indekslerin de güncellenmesi demektir. Gereksiz indeksler yazma hızınızı baltalar.

Not: Veri tutarlılığı ve normalizasyonun performansa etkisi için Bakınız: Veritabanı Normalizasyon Kuralları ve De-normalizasyon Stratejileri.

3. Sorgu Yazımında Yapılan "Pahalı" Hatalar

Kod yazarken bazen kolaya kaçarız ama bu alışkanlıklar veritabanı seviyesinde felaketlere yol açar.

"SELECT *" Hastalığı

İhtiyacınız olmayan sütunları çekmek, network trafiğini artırır ve veritabanının "Covering Index" (Sadece indeksi okuyarak yanıt verme) yeteneğini elinden alır. Her zaman sadece ihtiyacınız olan sütunları açıkça belirtin.

Fonksiyon Kullanımı ve SARGability

WHERE bloğunda bir sütunu bir fonksiyonun içine sokarsanız (Örn: WHERE YEAR(kayit_tarihi) = 2024), veritabanı o sütundaki indeksi kullanamaz. Bunun yerine WHERE kayit_tarihi >= '2024-01-01' AND kayit_tarihi <= '2024-12-31' gibi "Search Argumentable" (SARGable) ifadeler kullanmalısınız.

N+1 Sorgu Problemi

Özellikle ORM (Entity Framework, Hibernate vb.) kullananların en büyük kabusudur. Bir liste çekerken, listedeki her bir öğenin detayı için veritabanına tekrar tekrar gitmek yerine JOIN veya Eager Loading yöntemlerini tercih etmelisiniz.

4. Join Operasyonları ve Tablo İlişkileri

Veritabanı tuning işlemlerinin en çok ter dökülen kısmı join'lerdir. Dev tabloları birbirine bağlarken şunlara dikkat etmek hayat kurtarır:

  • Küçük Tabloyu Öne Almak: Bazı optimizers'lar bunu otomatik yapsa da, mantıksal olarak filtreleme sonrası en az kayıt döndüren tabloyu ana odak yapmak iyidir.
  • Data Type Uyumu: Join attığınız iki sütunun veri tipi (örn: biri INT diğeri BIGINT) aynı değilse, veritabanı her satırda tip dönüşümü (implicit conversion) yapar. Bu, CPU'yu boş yere yorar ve indeksi devre dışı bırakabilir.

5. İleri Seviye Teknikler: Böl ve Yönet

Eğer tablonuzda milyonlarca, milyarlarca satır varsa, standart yöntemler yetmeyebilir.

  • Partitioning (Bölümleme): Dev bir tabloyu mantıksal parçalara (örn: yıla göre veya bölgeye göre) ayırmak, sorgunun sadece ilgili bölüme bakmasını sağlar.
  • Materialized Views: Çok karmaşık ve sık değişmeyen raporlama sorgularını fiziksel bir tabloda önceden hesaplanmış şekilde tutmak, milisaniyeler içinde sonuç almanızı sağlar.
  • Locking ve Concurrency: Uzun süren sorgular tabloyu kilitler (Lock). Okuma işlemleri için NOLOCK (SQL Server) veya READ COMMITTED SNAPSHOT gibi izolasyon seviyelerini anlamak, sistemin kilitlenmesini önler.

Not: Donanımsal darboğazlar ve sunucu konfigürasyonu hakkında detaylı bilgi için Bakınız: Veritabanı Sunucusu Donanım ve OS Tuning.

Sonuç: Sürekli Bir Süreç

Veritabanı optimizasyonu bir kez yapılıp bitirilecek bir "görev" değildir. Veri büyüdükçe, kullanıcı davranışları değiştikçe sorguların performansı da değişir. Profesyonel bir yaklaşım için:

  • Monitoring: Yavaş sorguları (Slow Query Logs) düzenli takip edin.
  • Test: Optimizasyonu canlı ortamda değil, gerçek verinin bir kopyasıyla test ortamında yapın.
  • Basit Düşünün: Bazen en karmaşık sorgunun çözümü, sadece doğru bir WHERE koşulu eklemektir.

Veritabanınızın her zaman hızlı, sorgularınızın ise "Index Scan" tadında olması dileğiyle!