Gereksinimler ve Ön Hazırlık
Performans odaklı bir çalışma ortamı için aşağıdaki araçların güncel sürümlerine sahip olmanız gerekmektedir. 2026 yılı itibarıyla PostgreSQL 17+ veya MySQL 9.0+ sürümleri, gelişmiş sorgu planlayıcıları ile optimizasyon süreçlerini kolaylaştırmaktadır.
- Veritabanı Yönetim Sistemi: PostgreSQL veya MySQL (Yerel veya bulut tabanlı).
- İnceleme Aracı:
EXPLAIN ANALYZEkomutunu destekleyen bir SQL istemcisi (DBeaver, pgAdmin veya MySQL Workbench). - Veri Seti: Performans testleri için en az 100.000 satırlık örnek bir tablo yapısı.
Adım 1: Sorgu Planlayıcıyı Anlamak ve EXPLAIN Kullanımı
Bir sorgunun neden yavaş çalıştığını anlamanın ilk yolu, veritabanının o sorguyu nasıl işlediğini görmektir. EXPLAIN ANALYZE komutu, sorgunun çalışma planını, hangi indekslerin kullanıldığını ve işlemin ne kadar sürdüğünü detaylandırır.
EXPLAIN ANALYZE
SELECT * FROM siparisler
WHERE musteri_id = 4521
AND siparis_tarihi > '2026-01-01';
Bu kod bloğu, veritabanının ilgili tabloyu tararken bir "Sequential Scan" (tüm tabloyu satır satır okuma) mı yoksa "Index Scan" mi yaptığını gösterir. Eğer "Seq Scan" görüyorsanız, sorgunuz indekslenmemiş bir sütun üzerinde çalışıyor demektir.
Adım 2: İndeksleme Stratejileri ve Doğru Kullanım
İndeksler, veritabanının veriye ulaşma hızını artıran birer yol haritasıdır. Ancak gereğinden fazla indeks, veri ekleme (INSERT) ve güncelleme (UPDATE) işlemlerini yavaşlatır. İhtiyaca yönelik, seçici indeksler oluşturmak esastır.
-- İndeks oluşturma örneği
CREATE INDEX idx_musteri_siparis_tarih
ON siparisler (musteri_id, siparis_tarihi);
Bu örnekte, hem musteri_id hem de siparis_tarihi sütunlarını kapsayan bir "Composite Index" (bileşik indeks) oluşturduk. Bu, özellikle WHERE koşulunda bu iki sütunu birlikte kullanan sorgular için performansı dramatik şekilde artırır.
Adım 3: SELECT * Kullanımından Kaçınmak
Yeni başlayanların yaptığı en yaygın hata, ihtiyaç duyulmayan tüm sütunları çekmek için SELECT * kullanmaktır. Bu durum, ağ trafiğini artırır ve veritabanının gereksiz veri okumasına neden olur. Sadece gerekli sütunları belirtmek, "Covering Index" (kapsayıcı indeks) kullanımına da olanak tanır.
-- Yanlış kullanım
SELECT * FROM kullanicilar WHERE aktif = 1;
-- Doğru kullanım
SELECT id, ad, soyad FROM kullanicilar WHERE aktif = 1;
Sadece ihtiyaç duyulan sütunları çekmek, veritabanı belleğinin (RAM) daha verimli kullanılmasına ve sorgu yanıt süresinin azalmasına yardımcı olur.
Adım 4: JOIN Operasyonlarında Performans
Çoklu tablo birleştirmelerinde (JOIN), tabloların birbirine bağlandığı sütunların indeksli olması zorunludur. Ayrıca, INNER JOIN ile LEFT JOIN arasındaki mantıksal farkı iyi gözetmeli ve gereksiz birleştirme işlemlerinden kaçınmalısınız.
SELECT k.ad, s.tutar
FROM kullanicilar k
INNER JOIN siparisler s ON k.id = s.kullanici_id
WHERE s.tutar > 500;
Burada kullanici_id sütununun siparisler tablosunda indeksli olduğundan emin olmalısınız. Aksi takdirde, veritabanı her bir kullanıcı için tüm siparişler tablosunu taramak zorunda kalacaktır.
Adım 5: Veritabanı Optimizasyon Yöntemleri Karşılaştırması
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| İndeksleme | Okuma hızını artırır. | Yazma işlemlerini yavaşlatır. |
| Sütun Seçimi | Bellek tasarrufu sağlar. | Kodun güncellenmesini gerektirir. |
| Partitioning | Büyük veride hızlı erişim. | Karmaşık yönetim yapısı. |
Adım 6: Güvenlik ve Performans Dengesi
Kritik Uyarı: Performans artırımı yaparken güvenlikten ödün vermeyin. Asla kullanıcıdan gelen veriyi doğrudan sorguya eklemeyin. SQL Injection saldırılarına karşı her zaman "Prepared Statements" veya "Parameterized Queries" kullanın.
-- Güvenli sorgu örneği (PHP/PDO yaklaşımı)
$stmt = $pdo->prepare('SELECT ad FROM kullanicilar WHERE id = :id');
$stmt->execute(['id' => $kullaniciGirdisi]);
$kullanici = $stmt->fetch();
Bu yöntem, hem veritabanı sorgusunun önbelleğe alınmasını (query cache) sağlayarak performansı artırır hem de uygulamanızı SQL Injection saldırılarına karşı korur.
Sıkça Sorulan Sorular
İndeksler her zaman performansı artırır mı?
Hayır. Çok sık güncellenen tablolarda aşırı indeksleme, yazma işlemlerini yavaşlatır. İndeksler, okuma ağırlıklı işlemler için tasarlanmalıdır.
Sorgu planını nasıl okumalıyım?
EXPLAIN ANALYZE çıktısında "cost" değerlerine ve "rows" tahminlerine bakın. Eğer tahmin edilen satır sayısı ile gerçek satır sayısı çok farklıysa, istatistikleriniz güncel değildir.
İstatistikler neden önemlidir?
Veritabanı, sorguyu nasıl işleyeceğine tablodaki veri dağılımına bakarak karar verir. ANALYZE komutunu düzenli çalıştırarak istatistikleri güncel tutmalısınız.
Neden JOIN yerine Subquery kullanmamalıyım?
Modern veritabanı motorları JOIN işlemlerini optimize etmekte daha başarılıdır. Subquery (alt sorgu) kullanımı bazen veritabanı motorunun yanlış bir plan seçmesine neden olabilir.
Veritabanı sunucusu ile uygulama sunucusu aynı yerde mi olmalı?
Gecikmeyi (latency) azaltmak için veritabanı ve uygulama sunucularının aynı veri merkezi içerisinde olması, ağ performansını doğrudan iyileştirir.
İleri Düzey Teknikler: Veritabanı Partitioning ve Sharding Stratejileri
Veri setleriniz milyonlarca satıra ulaştığında, standart indeksleme yöntemleri bile sorgu sürelerini kısaltmada yetersiz kalabilir. Bu noktada, veritabanı mimarisini yatay veya dikey olarak parçalamak (Partitioning & Sharding) kaçınılmaz hale gelir. Partitioning, büyük bir tabloyu mantıksal parçalara bölerek sorgu motorunun sadece ilgili veri kümesini taramasını sağlar.
Partitioning Uygulama Örneği (PostgreSQL)
Örneğin, satış verilerini tutan bir tablonuz varsa, bu tabloyu tarih bazlı bölümlere ayırarak sorgu performansını ciddi oranda artırabilirsiniz:
CREATE TABLE satislar (
id SERIAL,
tarih DATE NOT NULL,
tutar DECIMAL
) PARTITION BY RANGE (tarih);
CREATE TABLE satislar_2023 PARTITION OF satislar
FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');
CREATE TABLE satislar_2024 PARTITION OF satislar
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
Bu yapı sayesinde, 2024 yılına ait verileri sorguladığınızda veritabanı motoru 2023 tablosunu tamamen görmezden gelir (Partition Pruning), bu da I/O maliyetini minimuma indirir.
Performans İzleme ve Hata Ayıklama (Query Profiling)
Sorgu optimizasyonu sadece kod yazarken değil, canlı sistemlerdeki darboğazları tespit ederken de devam eder. Yavaş sorguları tespit etmek için veritabanının sunduğu "Slow Query Log" özelliklerini aktif etmelisiniz.
Yavaş Sorguları Tespit Etme ve İyileştirme
MySQL üzerinde yavaş sorguları loglamak için aşağıdaki konfigürasyon adımlarını izleyebilirsiniz. Bu, uygulama performansını düşüren gizli "katil sorguları" bulmanıza yardımcı olur:
-- Yavaş sorgu logunu aktif et
SET GLOBAL slow_query_log = 'ON';
-- 2 saniyeden uzun süren sorguları kaydet
SET GLOBAL long_query_time = 2;
-- Hangi sorguların indeks kullanmadığını belirle
SET GLOBAL log_queries_not_using_indexes = 'ON';
Performans Metrikleri Tablosu
Sorgu iyileştirme sürecinde hedeflemeniz gereken temel metrikler şunlardır:
| Metrik | Hedef Değer | Açıklama |
|---|---|---|
| Query Latency | < 100ms | Standart bir okuma sorgusu için ideal süre. |
| Index Hit Rate | > 95% | Verinin disk yerine bellekten okunma oranı. |
| Deadlock Sayısı | 0 | Eşzamanlı işlemlerde çakışma olmamalıdır. |
Unutmayın ki, veritabanı optimizasyonu bir "kur ve unut" süreci değildir. Uygulamanız büyüdükçe veri dağılımı değişir; bu nedenle düzenli olarak ANALYZE komutunu çalıştırarak veritabanı istatistiklerini güncel tutmak, sorgu planlayıcının her zaman en verimli yolu seçmesini sağlar.
Sonuç
Sql & Veritabanı ile performans odaklı veri sorgulama optimizasyonu, sürekli takip ve iyileştirme gerektiren bir süreçtir. EXPLAIN ANALYZE ile sorgularınızı analiz etmeyi, doğru indeksleme stratejileri kurmayı ve her zaman güvenli kod yazmayı alışkanlık haline getirmelisiniz. Bir sonraki adım olarak, veritabanı "Caching" (önbellekleme) mekanizmalarını (Redis gibi) araştırmanızı ve sorgu sonuçlarını uygulama katmanında nasıl daha verimli saklayacağınızı öğrenmenizi öneririm.
Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) herhangi bir değişiklik yapmadan önce mutlaka veritabanı yedeği alınız ve değişiklikleri önce bir test ortamında doğrulayınız.


Yorumlar (0)
Yorum Yaz