Gereksinimler ve Ön Hazırlık
Optimizasyon süreçlerine başlamadan önce, veritabanı yönetim sisteminizin (DBMS) güncel olduğundan emin olmalısınız. PostgreSQL 17+, SQL Server 2025 veya MySQL 9.0 gibi güncel sürümler, gelişmiş sorgu iyileştirici (query optimizer) özelliklerine sahiptir.
- Veritabanı İstemcisi: DBeaver, pgAdmin veya SQL Server Management Studio (SSMS) gibi bir araç.
- İzleme Araçları: Sorgu çalışma sürelerini analiz etmek için "Query Store" veya "Explain Analyze" özelliklerinin aktif olması gerekir.
- Test Ortamı: Optimizasyon denemelerini asla canlı veritabanında değil, canlı verinin bir kopyasını içeren "Staging" ortamında yapmalısınız.
Saklı Yordamlarda "SET NOCOUNT ON" Kullanımı
SQL Server gibi sistemlerde, her sorgu çalıştırıldığında veritabanı motoru "x satır etkilendi" mesajını döndürür. Bu küçük mesaj paketi, binlerce döngü içeren yordamlarda ciddi bir ağ trafiği yükü oluşturur. Bunu devre dışı bırakmak, gereksiz veri transferini engeller.
CREATE PROCEDURE GetKullaniciSiparisleri
@KullaniciID INT
AS
BEGIN
SET NOCOUNT ON; -- Gereksiz mesaj paketlerini kapatır.
SELECT SiparisID, Tutar, Tarih
FROM Siparisler
WHERE KullaniciID = @KullaniciID;
END;
Bu kodda SET NOCOUNT ON komutu, sunucunun istemciye her işlem sonrası "kaç satır işlendi" bilgisini göndermesini engeller. Bu, özellikle büyük raporlama yordamlarında performans artışı sağlar.
Dinamik SQL Yerine Parametreli Sorguların Tercih Edilmesi
Dinamik SQL, sorgunun çalışma anında string birleştirme ile oluşturulmasıdır. Bu yöntem, veritabanının sorgu planını önbelleğe almasını (plan caching) zorlaştırır ve SQL Injection riskini doğurur. Parametreli sorgular, sorgu planının yeniden kullanılmasını sağlar.
-- Yanlış Kullanım (SQL Injection riski)
-- EXEC('SELECT * FROM Urunler WHERE Kategori = ''' + @Kategori + '''')
-- Doğru Kullanım (Parametreli ve Güvenli)
CREATE PROCEDURE UrunleriGetir
@Kategori NVARCHAR(50)
AS
BEGIN
SELECT UrunAd, Fiyat
FROM Urunler
WHERE Kategori = @Kategori;
END;
Parametreli yapılar, SQL Server veya PostgreSQL'in sorguyu bir kez derleyip planı belleğe almasına olanak tanır. İkinci kez aynı sorgu geldiğinde derleme aşaması atlanır, bu da milisaniyeler bazında hız kazandırır.
Sorgu Planı Analizi ve İndeksleme Stratejileri
Saklı yordamların yavaş çalışmasının temel nedeni genellikle eksik indekslerdir. Sorgu planını analiz ederek hangi tablolarda "Table Scan" (tüm tablonun taranması) yapıldığını görebilir ve gerekli indeksleri oluşturabilirsiniz.
-- Sorgu planını analiz etmek için (PostgreSQL örneği)
EXPLAIN ANALYZE
SELECT * FROM Siparisler WHERE KullaniciID = 123;
-- İndeks oluşturma komutu
CREATE INDEX IX_Siparisler_KullaniciID ON Siparisler(KullaniciID);
EXPLAIN ANALYZE komutu, sorgunun hangi aşamalarda ne kadar süre harcadığını gösterir. Eğer bir "Seq Scan" görüyorsanız, ilgili kolona indeks eklemeniz gerektiği anlamına gelir.
Tablo Karşılaştırma: Optimizasyon Yöntemleri
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| SET NOCOUNT ON | Ağ trafiğini azaltır | Hata ayıklamayı zorlaştırabilir |
| Parametreli Sorgu | Plan önbellekleme, Güvenlik | Karmaşık dinamik yapılarda zorluk |
| İndeksleme | Okuma hızını artırır | Yazma (INSERT/UPDATE) hızını düşürür |
Veri Kümesi Yönetimi: Cursor Yerine Set-Based İşlemler
Yazılımcılar bazen verileri satır satır işlemek için "Cursor" (imleç) yapısını kullanırlar. Bu, veritabanı dünyasındaki en büyük performans hatalarından biridir. Bunun yerine "Set-Based" (küme tabanlı) işlemleri tercih etmelisiniz.
-- Kötü Uygulama (Cursor kullanımı - YAVAŞ)
-- Satır satır döngü kurmak yerine set bazlı işlem yapın.
-- İyi Uygulama (Set-Based işlem)
UPDATE Urunler
SET Fiyat = Fiyat * 1.10
WHERE KategoriID = 5;
Küme tabanlı işlemler, veritabanı motorunun optimize edici yeteneklerini tam kapasite kullanmasını sağlar. Cursor kullanımı, veritabanını bir "işlemci" gibi değil, bir "dosya okuyucu" gibi çalışmaya zorlar.
Kritik Güvenlik Uyarısı: Saklı yordamlarınızda asla kullanıcıdan gelen veriyi doğrudan (concatenation) SQL komutuna dahil etmeyin. Her zaman parametre kullanın. Ayrıca, veritabanı kullanıcısına sadece ihtiyacı olan yetkileri (EXECUTE yetkisi gibi) verin; 'sa' veya 'root' yetkileriyle uygulama çalıştırmayın.
Sıkça Sorulan Sorular
Saklı yordamlar neden her zaman daha hızlı değildir?
Eğer sorgu çok basitse ve tek bir tabloyu hedefliyorsa, saklı yordamın sağladığı derleme avantajı, ağ trafiği tasarrufu ile dengelenmeyebilir. Çok karmaşık olmayan sorgularda ORM (Object-Relational Mapping) araçlarının ürettiği sorgular yeterli olabilir.
"Parameter Sniffing" nedir ve nasıl çözülür?
Veritabanı motorunun, yordamın ilk çalıştırıldığı parametreye göre bir sorgu planı oluşturup bunu diğer parametreler için de kullanmasıdır. Eğer parametreler çok farklı veri dağılımlarına sahipse, OPTION (RECOMPILE) komutu ile yordamı her çalışmada yeniden derlenmeye zorlayabilirsiniz.
İndeksleri ne zaman güncellemeliyim?
İstatistikler (Statistics) güncel değilse, veritabanı motoru yanlış bir yürütme planı seçebilir. Düzenli aralıklarla veritabanı istatistiklerini güncellemek (Update Statistics) performansın korunmasını sağlar.
Saklı yordam mı yoksa uygulama tarafında yazılan SQL mi?
Güvenlik ve veritabanı üzerinde merkezi yönetim gerektiren durumlarda saklı yordamlar; esneklik ve hızlı geliştirme gerektiren durumlarda ise uygulama tarafındaki sorgular tercih edilir.
Optimizasyon yaparken nelere dikkat etmeliyim?
Önce en yavaş çalışan sorguları tespit edin. "En çok kaynak tüketen 10 sorgu" listesini çıkararak işe başlayın. Ezbere indeks eklemek yerine, sorgu planı analizine dayalı indeksleme yapın.
İleri Düzey Hata Ayıklama ve Performans İzleme Teknikleri
Saklı yordamlarınızın performansını optimize ettikten sonra, bu iyileştirmelerin canlı ortamda nasıl tepki verdiğini izlemek kritiktir. SQL Server Profiler veya Extended Events kullanarak, yordamlarınızın çalışma süresini, okunan sayfa sayısını (logical reads) ve CPU kullanımını anlık olarak takip edebilirsiniz. Özellikle Extended Events, Profiler'a göre çok daha düşük bir sistem yükü oluşturduğu için üretim ortamlarında tercih edilmelidir.
Aşağıdaki sorgu, veritabanınızdaki en çok CPU tüketen saklı yordamları tespit etmenize yardımcı olur:
SELECT TOP 10
OBJECT_NAME(st.objectid, st.dbid) AS ProcedureName,
qs.total_worker_time / 1000 AS TotalCPU_ms,
qs.execution_count,
qs.total_elapsed_time / 1000 AS TotalDuration_ms,
st.text AS QueryText
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
WHERE st.objectid IS NOT NULL
ORDER BY qs.total_worker_time DESC;
Hata Ayıklama (Debugging) Süreçlerinde TRY-CATCH Blokları
Optimizasyon sırasında yapılan değişiklikler bazen beklenmedik çalışma zamanı hatalarına yol açabilir. Saklı yordamlarınızda hata ayıklamayı kolaylaştırmak ve sistemin tutarlılığını korumak için mutlaka TRY...CATCH bloklarını kullanmalısınız. Bu yapı, hata anında işlemin geri alınmasını (rollback) sağlar ve hata detaylarını loglamanıza olanak tanır.
CREATE PROCEDURE usp_UpdateInventory
@ProductID INT,
@Quantity INT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
UPDATE Inventory SET Stock = Stock - @Quantity WHERE ProductID = @ProductID;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
-- Hata loglama tablosuna yazma işlemi
INSERT INTO ErrorLog (ErrorNumber, ErrorMessage, ErrorTime)
VALUES (ERROR_NUMBER(), ERROR_MESSAGE(), GETDATE());
END CATCH
END;
Deployment ve Sürüm Kontrol Stratejileri
Saklı yordamlarınızı geliştirme ortamından canlı ortama taşırken, "Migration" (göç) süreçlerini otomatize etmek, performans kaybını önleyen kritik bir adımdır. Kodunuzu doğrudan veritabanı üzerinde değiştirmek yerine, bir sürüm kontrol sistemi (Git gibi) kullanarak yordamlarınızı dosya bazlı yönetmelisiniz.
- Script Standartları: Her yordamın başına oluşturulma tarihini ve yapılan değişikliklerin kısa bir özetini içeren yorum satırları ekleyin.
- Bağımlılık Analizi: Bir yordamı güncellemeden önce, o yordama bağımlı olan diğer görünümleri (views) veya tetikleyicileri (triggers)
sys.dm_sql_referencing_entitiesile kontrol edin. - Test Ortamı: Optimizasyon sonrası yordamları, canlı veritabanının bir kopyası (anlık yedeği) üzerinde "Load Test"e tabi tutarak, indeks değişikliklerinin diğer sorgular üzerindeki yan etkilerini gözlemleyin.
Unutmayın ki, en iyi optimize edilmiş saklı yordam bile, veritabanı sunucusunun genel konfigürasyonu (Memory, Max Degree of Parallelism - MAXDOP) yanlış ayarlanmışsa tam performansla çalışamaz. Sunucu seviyesindeki ayarlar ile yordam seviyesindeki optimizasyonları bir bütün olarak değerlendirmek, sürdürülebilir bir veritabanı mimarisi için zorunludur.
Sonuç
SQL & Veritabanı ile uygulamalar için veri saklı yordam optimizasyonu, veritabanı motorunun çalışma prensiplerini anlamaktan geçer. SET NOCOUNT ON kullanımı, parametreli sorguların tercih edilmesi, "Set-Based" mantığına geçiş ve doğru indeksleme stratejileri ile uygulamalarınızın yanıt sürelerini ciddi oranda düşürebilirsiniz. Bir sonraki adım olarak, veritabanınızdaki "Lock" (kilitlenme) mekanizmalarını inceleyerek, eşzamanlı işlemlerdeki darboğazları nasıl çözeceğinizi araştırmanızı öneririm.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri genel eğitim amaçlıdır. Uygulama ortamınızdaki veritabanı şemasına göre test edilmeli ve güvenlik politikalarınızla uyumlu hale getirilmelidir.


Yorumlar (0)
Yorum Yaz