SQL Performans İyileştirmeleri: Sorgu Optimizasyonu ve İndeks Örnekleri
Veri Tabanı Yönetimi ve Optimizasyonu
SQL Performans İyileştirmeleri: Sorgu Optimizasyonu ve İndeks Örnekleri

SQL Performans İyileştirmeleri: Sorgu Optimizasyonu ve İndeks Örnekleri
Veritabanı sorgularının yavaş çalışması, uygulama tepki sürelerini artırır ve kaynak kullanımını yükseltir. Bu makale, SQL sorgu optimizasyonu ve indeksleme için pratik, uygulanabilir adımlar sunar. Aşağıdaki teknikler genel olarak MySQL/MariaDB ve benzeri ilişkisel veritabanlarında geçerlidir; belirli komutların sözdizimi veritabanı motoruna göre değişebilir.
Temel prensipler
İyi bir optimizasyon süreci şu temel prensipler üzerine kuruludur:
- Doğru veri tipleri: Alanların gereksinime uygun veri tipinde tanımlanması bellek ve disk kullanımını azaltır, indekslerin daha etkin çalışmasını sağlar (kaynak: Semih Bebek).
- Gereksiz veri çekiminden kaçının: SELECT * yerine yalnızca gerekli sütunları seçin; bu ağ ve I/O maliyetlerini düşürür (kaynak: Semih Bebek).
- İndeksleri akıllıca kullanın: WHERE, JOIN ve ORDER BY koşullarında kullanılan sütunlara uygun indeksler ekleyin ama aşırı indekslemeden kaçının (kaynak: IHS Blog).
- Fonksiyonlardan kaçının: WHERE içinde sütun üzerinde fonksiyon kullanmak indekslerin kullanılmasını engelleyebilir; mümkünse sabitleri dönüştürün veya aralık sorguları kullanın (kaynak: Kızıltaş).
- Planı analiz edin: EXPLAIN gibi araçlarla sorgu planını inceleyin; hangi indekslerin kullanıldığını, tablo taramalarını ve sıralama/temporary işlemlerini tespit edin (kaynak: Türk Ticaret).
Adım adım: Sorgu optimizasyonu akışı
- Ölçüm yapın: Önce hangi sorguların problem yarattığını tespit edin. Uygulama profilleri, slow-query log veya APM araçları kullanın.
- Yineleyin ve çoğaltın: Sorunlu sorguyu staging ortamında yeniden çalıştırın; değişiklikleri burada test edin.
- Planı inceleyin: EXPLAIN ile sorgu planını alın ve tam tablo taraması (full table scan), USING TEMPORARY veya USING FILESORT gibi uyarılara bakın (Türk Ticaret).
- Sorgu yeniden yazımı: SELECT *'ten kaçının, alt sorguları gerekirse JOIN ile değiştirin, filtreleri mümkün olduğunca erken uygulayın.
- İndeks ekleme/düzenleme: Sorguda kullanılan filtreleme, birleştirme ve sıralama sütunlarına uygun indeksler oluşturun. Test edin; her indeks eklemenin yazma maliyeti olduğunu unutmayın.
- Test ve izleme: Değişiklikleri A/B test ya da zaman serisi izleme ile doğrulayın; üretimde sürekli izleme yapın.
Pratik SQL örnekleri
1) SELECT * yerine sadece gerekli sütunları seçin
-- Kötü: gereksiz sütun çekiyor SELECT * FROM orders WHERE created_at > '2024-01-01'; -- İyi: sadece gereken sütunlar SELECT id, customer_id, total_amount FROM orders WHERE created_at > '2024-01-01';
Açıklama: Ağ ve I/O maliyetlerini düşürmek için taşıma verisini azaltın. Bu özellikle geniş tablolar veya sık sorgulanan API uç noktaları için önemlidir (Semih Bebek).
2) WHERE içinde fonksiyon kullanmaktan kaçının
-- Kötü: indeks kullanılmasını engelleyebilir SELECT id FROM events WHERE DATE(event_time) = '2025-03-01'; -- İyi: aralık kullanmak indeksin çalışmasına izin verir SELECT id FROM events WHERE event_time >= '2025-03-01' AND event_time < '2025-03-02';
Açıklama: Sütun üzerinde fonksiyon çalıştırmak, indeks taramalarını etkileyebilir. Sabitleri dönüştürerek veya aralık sorguları kullanarak indekslerden faydalanın (Kızıltaş).
3) JOIN'lerde indeks kullanımı
-- Kötü: join sütunlarında indeks yok SELECT o.id, c.name FROM orders o JOIN customers c ON o.customer_code = c.code WHERE c.status = 'active'; -- İyi: ilgili sütunlara indeks ekleyin CREATE INDEX idx_customers_code ON customers(code); CREATE INDEX idx_orders_customer_code ON orders(customer_code); SELECT o.id, c.name FROM orders o JOIN customers c ON o.customer_code = c.code WHERE c.status = 'active';
Açıklama: JOIN koşullarında kullanılan sütunların indeksli olması genellikle performansı iyileştirir. Yine de indeks seçimi tablo boyutu ve kardinaliteye bağlıdır; her durum farklı test gerektirir (Kızıltaş).
4) Kompozit ve covering indeks örneği
-- Sorgu: belirli bir müşteri için en son siparişleri getir SELECT id, status, created_at FROM orders WHERE customer_id = 123 ORDER BY created_at DESC LIMIT 10; -- Önerilen indeks (customer_id, created_at) veya covering indeks (customer_id, created_at, status) CREATE INDEX idx_orders_customer_date ON orders(customer_id, created_at);
Açıklama: Kompozit indekslerde sütunların sırası önemlidir; önce WHERE ya da sık filtrelenen sütun gelmelidir. Eğer sorgu yalnızca indeks sütunlarını döndürürse "covering index" tabloya erişmeden sonucu sağlayabilir ve performansı artırabilir (IHS Blog).
EXPLAIN ile sorgu planı okuma (kısa rehber)
EXPLAIN çıktısında dikkat etmeniz gereken bazı alanlar:
- type: 'ALL' tam tablo taraması; 'range', 'ref', 'const' gibi değerler daha iyi performans gösterebilir.
- possible_keys / key: Sorgunun kullanabileceği indeksler ve gerçekten kullanılan indeks.
- rows: Tahmini taranan satır sayısı; yüksek değerler optimizasyon gerektirebilir.
- Extra: 'Using temporary' veya 'Using filesort' gibi ifadeler varsa sorgu yeniden yazılabilir.
| Field | Kısa Açıklama |
|---|---|
| type | Sorgu türü; 'ALL' ise full table scan anlamına gelebilir. |
| key | Kullanılan indeks. |
| rows | Tahmini taranan satır sayısı. |
EXPLAIN sonuçlarını yorumlarken üretim verileriyle benzer veri dağılımını kullanmaya çalışın; küçük test setleri yanıltıcı olabilir (Türk Ticaret).
İndeks yönetimi ve bakım
- Gereksiz veya yinelenen indeksleri düzenli olarak kaldırın; fazla indeks yazma işlemlerini yavaşlatır.
- Veri dağılımı değiştiğinde istatistikleri güncelleyin (ANALYZE TABLE gibi araçlar). Bunlar MySQL/MariaDB ortamlarında sorgu optimizasyonuna yardımcı olur (IHS Blog).
- Büyük veri değişikliklerinden sonra indeks yeniden oluşturma veya optimize etme gerekebilir.
- İndekslerin disk kullanımını takip edin; depolama maliyetini ve bakım süresini göz önünde bulundurun.
Ne zaman indeks eklememelisiniz?
Tüm sütunlara indeks eklemek mantıklı değildir. Düşük kardinaliteli sütunlar (ör. boolean) genellikle fayda sağlamaz. Ayrıca çok küçük tablolar doğal olarak hızlıdır; indeks maliyeti gereksiz olabilir. Her indeks eklemeden önce test edin ve yazma maliyetlerini değerlendirin (IHS Blog).
Dağıtıma hazırlık checklist
- Değişiklikleri staging ortamında doğrulayın.
- Ölçümler yapın: sorgu süresi, taranan satır sayısı, CPU ve I/O kullanımı.
- Yedek alın ve geri alma planı hazırlayın.
- Değişiklikleri parça parça dağıtın ve izleyin.
- Üretimde slow-query log ve APM ile sürekli izleme kurun.
Sonuç
SQL performans iyileştirmesi disiplinli bir süreçtir: ölçüm, analiz, yeniden yazım, indeksleme ve izleme adımlarını içerir. Bu rehberdeki basit kontrollere (doğru veri tipi, SELECT iyileştirmesi, doğru indeks, fonksiyon kullanımından kaçınma, EXPLAIN ile analiz) öncelik vererek büyük iyileştirmeler elde edebilirsiniz. Değişiklikleri üretimde uygulamadan önce staging ortamında test edin ve izleme ile sonucu doğrulayın.
Daha derin rehberler ve örnek incelemeler için aşağıdaki kaynaklara bakabilirsiniz: