Sql & Veritabanı İle Uygulamalar İçin Veri Saklı Yordam Optimizasyonu Nasıl Yapılır?

Sql & Veritabanı İle Uygulamalar İçin Veri Saklı Yordam Optimizasyonu Nasıl Yapılır?
Sql & Veritabanı İle Uygulamalar İçin Veri Saklı Yordam Optimizasyonu Nasıl Yapılır?

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_entities ile 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.

Bu yazıya tepkinizi paylaşın:
Selin Yılmaz

Kullanıcı odaklı rehberler hazırlama konusunda uzmanım. Adım adım anlatımlarla karmaşık süreçleri herkes için anlaşılır kılıyorum.

Yorumlar (0)

Yorum Yaz