← Blog
12 Eylül 2026· otomatik üretildi

SQL ile Raporları Hızlandırmak: İndeksler ve Sorgu İpuçları

Yavaş çalışan SQL raporları can sıkıcı olabilir. İndeksler ve akıllı sorgu teknikleriyle performansı dramatik biçimde artırmanın yollarını keşfedelim.

#SQL#performans#indeks#veri

Bir rapor sayfası açıyorsunuz, ekran donuyor, dakikalarca bekliyorsunuz. Tanıdık geldi mi? Yavaş SQL sorguları sadece sinir bozucu değil; üretim sistemlerinde gerçek bir maliyet kalemi. Bu yazıda raporlarınızı hızlandırmak için kullandığım pratik teknikleri paylaşacağım.

Sorunun Kaynağını Bulmak: EXPLAIN Planı

Her şeyden önce, "neden yavaş?" sorusunu yanıtlamak gerekiyor. Bunun için en güçlü silah EXPLAIN (veya SQL Server'da SET STATISTICS IO ON) komutudur.


EXPLAIN ANALYZE
SELECT * FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE o.created_at > '2024-01-01';

Çıktıda Seq Scan (sıralı tarama) görüyorsanız alarm zilleri çalmalı. Bu, veritabanının tablonun tamamını satır satır taradığı anlamına gelir; büyük tablolarda bu felakettir.

İndeksler: Doğru Yerde, Doğru Türde

İndeks koymak iyidir, ama her yere indeks koymak daha da kötü olabilir. İşte dikkat ettiğim kurallar:

Hangi Sütunlara İndeks Açılmalı?

  • WHERE koşullarında sık kullanılan sütunlar
  • JOIN anahtarları (foreign key sütunları)
  • ORDER BY ve GROUP BY içinde geçen sütunlar
  • Yüksek kardinaliteye sahip sütunlar (cinsiyet gibi yalnızca 2 değer alan sütunlara indeks genellikle işe yaramaz)

Bileşik (Composite) İndeks Sırası Önemli


-- Yanlış sıra: filtreleme önce status, sonra date ise
CREATE INDEX idx_orders ON orders (status, created_at);

-- Doğru sıra: en seçici sütun öne
CREATE INDEX idx_orders ON orders (created_at, status);

Bileşik indekste sütun sırası, kitaptaki dizin mantığıyla aynı: önce genel, sonra özel.

Kapsayıcı (Covering) İndeks

Sorgunun ihtiyaç duyduğu tüm sütunları indekse dahil ederseniz, veritabanı asıl tabloya hiç dokunmaz:


CREATE INDEX idx_covering ON orders (created_at)
INCLUDE (customer_id, total_amount, status);

Bu teknik özellikle yoğun raporlama sorgularında muazzam fark yaratır.

Sorgu Yazım İpuçları

İndeks ne kadar iyi olursa olsun, sorguyu yanlış yazarsanız sizi kurtaramaz.

SELECT * Kullanmayın

Sadece ihtiyacınız olan sütunları çekin. Hem ağ trafiği azalır hem de covering indekslerden yararlanabilirsiniz.

Fonksiyonları WHERE İçinde Kullanmaktan Kaçının


-- İndeksi devre dışı bırakır ❌
WHERE YEAR(created_at) = 2024

-- İndeksi kullanır ✅
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31'

Gereksiz JOIN'lerden Kurtulun

Raporda kullanılmayan tablolara JOIN atmayın. Her ek JOIN, sorgu planını karmaşıklaştırır.

WITH (CTE) ile Okunabilirlik + Performans

Karmaşık raporları CTE ile parçalara bölmek hem okunabilirliği artırır hem de optimizer'ın daha iyi plan üretmesine yardımcı olabilir:


WITH monthly_sales AS (
    SELECT DATE_TRUNC('month', created_at) AS month,
           SUM(total_amount) AS revenue
    FROM orders
    WHERE status = 'completed'
    GROUP BY 1
)
SELECT * FROM monthly_sales ORDER BY month;

İstatistikleri Güncel Tutun

Veritabanı, sorgu planını istatistiklere göre üretir. Tablolar büyüdükçe istatistikler eskir ve optimizer yanlış kararlar alır. Periyodik olarak:


ANALYZE orders; -- PostgreSQL
-- veya
UPDATE STATISTICS orders; -- SQL Server

komutlarını çalıştırmayı alışkanlık haline getirin.

Sonuç

SQL performansı bir kez yapıp unutulan bir iş değil. Veriler büyüdükçe, sorgular değiştikçe yeniden gözden geçirmek gerekiyor. Benim rutenim: önce EXPLAIN ile darboğazı bul, sonra doğru indeksi ekle, son olarak sorguyu sadeleştir. Bu üç adım, vaka vaka çalışıyor.

Sizin en çok hangi sorgu tipi başınızı ağrıtıyor? Yorumlarda buluşalım.