Wenn ETL zur Bremse wird

Viele ETL-Prozesse sind historisch gewachsen.
Und heute: langsam, schwer wartbar, fehleranfällig.

Meist läuft’s so:
Daten aus System A → Staging → Transformationen → Zielsystem B
Und dazwischen: unnötige Kopien, Casts, Cursor, Abfragen ohne Filter.

Wenn Du willst, dass der Datenfluss effizient bleibt, musst Du aufräumen.
Ich zeig Dir, wo Du ansetzen kannst.

Typische ETL-Sünden

ProblemFolge
Kein WHERE bei Datenzugriffunnötiger Traffic
Cursors statt Setsviel CPU, wenig Nutzen
SpaltenkonvertierungenI/O + CPU + schlechte Indizes
Fehlerhandling im SSISschwer nachvollziehbar
Kein Logging der SchritteDebuggen wird Ratespiel

Datenmenge begrenzen – direkt an der Quelle

-- Schlechte Variante
SELECT * FROM ERP.Produkte;

-- Besser
SELECT id, bezeichnung, preis
FROM ERP.Produkte
WHERE aktiv = 1
AND geändert_am >= @letztes_Laufdatum;

Erst holen, was wirklich gebraucht wird.
Und lieber kleine Deltas als Vollabzüge.

Kein CAST im Ziel, sondern sauber typisieren

-- Falsch: Conversion bei Insert
INSERT INTO DWH.Ziel
SELECT 
    CAST(id AS INT),
    CAST(preis AS DECIMAL(10,2))
FROM Staging.Quelle;

-- Besser: gleich in Staging korrekt definieren

Staging-Tabellen sollten das Format des Quellsystems exakt spiegeln.
Transformationen gehören danach.

Row-by-Row vermeiden

-- Cursor? Lass es.
DECLARE cur CURSOR FOR
SELECT kunde_id FROM dbo.Kunden;

-- Besser: set-based arbeiten
INSERT INTO DWH.Segmente
SELECT kunde_id, 'NEU'
FROM dbo.Kunden
WHERE erstellt_am >= @stichtag;

Set-basierte Operationen sind schneller, einfacher zu warten und paralleler nutzbar.

Robustheit durch Logging

INSERT INTO ETL.Log (prozess, startzeit, status)
VALUES ('Kundentransfer', GETDATE(), 'gestartet');

-- Schritte ausführen...

UPDATE ETL.Log
SET status = 'erfolgreich', endzeit = GETDATE()
WHERE prozess = 'Kundentransfer'
AND status = 'gestartet';

So weißt Du:

  • wann lief was?
  • wie lange?
  • mit welchem Ergebnis?

Fehlerbehandlung direkt in SQL

BEGIN TRY
    -- z. B. Upsert-Logik
    MERGE INTO dbo.KundenZiel AS ziel
    USING dbo.KundenNeu AS quelle
    ON ziel.id = quelle.id
    WHEN MATCHED THEN
        UPDATE SET ziel.name = quelle.name
    WHEN NOT MATCHED THEN
        INSERT (id, name) VALUES (quelle.id, quelle.name);
END TRY
BEGIN CATCH
    INSERT INTO ETL.Fehlerlog
    VALUES (ERROR_MESSAGE(), GETDATE(), 'Kunden-MERGE');
END CATCH

Wenn was schiefgeht, weißt Du wenigstens wo.

Performance-Tipp: Minimal Logging aktivieren

-- Nur bei einfachen Inserts in leere Tabellen
ALTER TABLE dbo.StagingTab
SWITCH TO dbo.ZielTab;

-- Oder:
SELECT * INTO dbo.Temp FROM Quelle WITH (TABLOCK);

So nutzt Du minimal logging – spart I/O und Transaction Log.

Ausblick: Weg vom SSIS-Monolithen

Wenn Du noch alles im SSIS hast:
Splitte auf:

  • SQL-Stored Procedures für Transformationen
  • Powershell für Orchestrierung
  • SQL Agent für Scheduling
  • Logging in eigener ETL-Logtabelle

So bist Du flexibler, schneller, portabler.
Gerade bei hybriden Architekturen.

Mein Fazit

Gute ETL-Prozesse sind wie gute Lagerlogistik:
Klarer Fluss, wenig Umwege, keine Dopplungen.

Tags:

No responses yet

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert