ETL Performansı Neden Düşer?

ETL (Extract, Transform, Load) süreçleri, veri ambarının can damarıdır. Ancak zamanla veri hacimleri büyür, iş kuralları karmaşıklaşır ve bir zamanlar 30 dakikada biten yükleme işlemi 3 saate çıkar. Eğer ETL penceresi iş saatlerine taşıyorsa, raporlarınız eski veriyle çalışıyor demektir.

En yaygın performans sorunları:

  • Satır-satır işleme (Row-by-Row): Küme işleme yerine her satırı tek tek işleme
  • Gereksiz veri çekme: Tüm tabloyu çekmek yerine yalnızca değişen verileri çekmek
  • Kötü INDEX stratejisi: Kaynak ve hedef tablolarda eksik index'ler
  • Aşırı dönüşüm: ETL katmanında yapılması gerekmeyen hesaplamalar
  • Seri çalışma: Paralel çalışabilecek görevlerin sıralı çalıştırılması
Optimize Edilmiş ETL Akışı
EXTRACTVeri KaynaklarıTRANSFORMTemizle & DönüştürLOADVeri Ambarı

1. Incremental Loading (Artımlı Yükleme)

En büyük performans kazanımı tam yükleme (Full Load) yerine artımlı yükleme (Incremental Load) kullanmaktır. Sadece son yüklemeden bu yana değişen kayıtları çekmek, veri hacmini %90+ azaltabilir.

SQL
-- SQL Server: Change Tracking ile artımlı yükleme
-- Yalnızca değişen satırları çek
SELECT s.*
FROM Satislar s
INNER JOIN CHANGETABLE(CHANGES Satislar, @son_sync_version) AS ct
    ON s.SatisID = ct.SatisID
WHERE ct.SYS_CHANGE_VERSION > @son_sync_version;

Artımlı Yükleme Stratejileri

💡CDC (Change Data Capture) ve Timestamp en performanslı yöntemlerdir. Trigger bazlı yaklaşım kaynak sisteme yük bindirir — mümkünse kaçının.

2. Set-Based İşleme

ETL'deki en yaygın performans katili: satır-satır (Row-by-Row) işleme. Bunun yerine küme bazlı (Set-Based) işleme kullanın.

SQL
-- ❌ YANLIŞ: Cursor ile satır satır güncelleme
DECLARE @id INT, @tutar DECIMAL
DECLARE cur CURSOR FOR SELECT SatisID, Tutar FROM Satislar
OPEN cur
FETCH NEXT FROM cur INTO @id, @tutar
WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE HedefTablo SET Tutar = @tutar WHERE SatisID = @id
    FETCH NEXT FROM cur INTO @id, @tutar
END

-- ✅ DOĞRU: Set-based MERGE işlemi
MERGE HedefTablo AS h
USING Satislar AS s
    ON h.SatisID = s.SatisID
WHEN MATCHED THEN
    UPDATE SET h.Tutar = s.Tutar
WHEN NOT MATCHED THEN
    INSERT (SatisID, Tutar) VALUES (s.SatisID, s.Tutar);
⚠️Cursor ve WHILE döngüleri ETL'de performans katilidir. SQL Server'da MERGE, Informatica'da Joiner + Update Strategy kullanın.

3. Paralel İşleme

Bağımsız görevleri paralel çalıştırmak toplam süreyi dramatik şekilde düşürür.

SSIS'te Paralel İşleme

SQL
-- SSIS: MaxConcurrentExecutables ayarı
-- Package Properties > MaxConcurrentExecutables = -1 (CPU sayısı kadar)
-- Her Data Flow Task bağımsız bir thread'de çalışır

-- Ayrıca her Data Flow içinde:
-- DefaultBufferMaxRows = 100000 (varsayılan 10000'den artır)
-- DefaultBufferSize = 10485760 (10MB)
-- EngineThreads = 10

4. Staging Stratejisi

Kaynak sistemden çekilen ham verileri doğrudan hedef tablolara yazmak yerine, Staging tabloları kullanın. Bu sayede:

Staging Katmanlı ETL Mimarisi
KaynaklarERP, CRM, APIStagingHam VeriVeri AmbarıStar SchemaRaporlamaPower BIUçtan Uca Veri Pipeline Mimarisi
  • Kaynak sistem bağlantı süresi minimize edilir
  • Transform işlemleri staging üzerinde yapılır
  • Hata durumunda staging'den tekrar yüklenebilir
  • Kaynak ve hedef birbirinden izole olur
SQL
-- Staging: TRUNCATE + BULK INSERT paterni
TRUNCATE TABLE Staging.Satislar;

BULK INSERT Staging.Satislar
FROM '\\sunucu\veri\satis_export.csv'
WITH (
    FIELDTERMINATOR = ';',
    ROWTERMINATOR = '\n',
    FIRSTROW = 2,
    TABLOCK  -- Tablo kilidi ile hızlı yükleme
);

-- Staging'den DWH'a MERGE
MERGE DWH.FactSatis AS h
USING Staging.Satislar AS s
    ON h.SatisKey = s.SatisKey
WHEN MATCHED AND h.Tutar <> s.Tutar THEN
    UPDATE SET h.Tutar = s.Tutar, h.GuncellemeTarihi = GETDATE()
WHEN NOT MATCHED THEN
    INSERT (SatisKey, Tutar, YuklemeTarihi)
    VALUES (s.SatisKey, s.Tutar, GETDATE());

5. Index ve Partition Stratejileri

| Strateji | Ne Zaman | Kazanım |

|---|---|---|

| Clustered Index | Fact tablolarında tarih kolonu | Sorgularda range scan |

| Nonclustered Index | Dimension lookup kolonları | JOIN performansı |

| Columnstore Index | Büyük Fact tabloları (10M+ satır) | Analitik sorgu hızı 10-100x |

| Table Partitioning | Zaman bazlı Fact tabloları | Partition switching ile anlık yükleme |

SQL
-- Partition switching: Downtime sıfır yükleme
-- 1. Staging tablosuna yükle
-- 2. Index oluştur
-- 3. Constraint ekle
-- 4. Switch (anlık!)

ALTER TABLE Staging.FactSatis_202601
SWITCH TO DWH.FactSatis PARTITION 25;
-- Bu işlem milisaniyeler sürer!
💡Columnstore Index kullanmak, büyük Fact tablolarında analitik sorguları 10-100 kat hızlandırabilir. SQL Server 2016+ ve Azure SQL'de kullanılabilir.

Performans Karşılaştırma Özeti

Sonuç

ETL optimizasyonu, veri ambarı performansının en etkili iyileştirme alanıdır. Artımlı yükleme, küme bazlı işleme, paralel çalışma, staging katmanı ve doğru index stratejileri ile ETL sürelerinizi 10 kata kadar kısaltabilirsiniz. Önemli olan sistematik yaklaşım: önce darboğazı tespit edin (ölçün!), sonra en büyük kazanımı sağlayacak optimizasyondan başlayın.