Lukas Lötters

„Die SSIS Script-Komponente des Microsoft SQL Servers kannst Du dafür nicht verwenden, die ist viel zu langsam!“, sagt eine Kollege neulich zu mir. Das machte mich neugierig. Basiert die Script-Komponenten doch auf dem gleichen Objektmodell wie alle anderen Komponenten auch. Der Code wird vor dem Deployment kompiliert. Aus dem Bauch heraus hätte ich gesagt, dass die Script-Komponenten nicht langsamer als alle anderen Komponenten des SSIS-Dataflows ist. Meine Neugier war geweckt. Wir isolierten den Code und stellen mehrere Testserien zusammen. Herhalten musste ein Laptop mit einer virtuellen Umgebung. Dieser wurden 2 CPUs und 2GB RAM zugewiesen. Es wurde ein Dataflow definiert, der wie folgt aussah:

Aufbau des SSIS-Testpakets

Aufbau des SSIS-Testpakets

Aufbau des SSIS-Testpakets

Die Daten wurden mit der zu testenden Script-Komponente generiert und es wird ein Dataset gefüllt. Das Dataset verfügt über sämtliche für BI relevanten Datentypen:

Datentypen

Datentypen

Die Felder werden in allen nachfolgenden Tests so gefüllt, dass eine Zeile 100Byte Nutzdaten enthält. Sämtliche Tests wurden mit 1Mio Zeilen durchgeführt. Am Ende des Data-Flow ist eine weitere dummy Script-Komponenten implementiert. Script-Komponenten haben den Vorteil, dass der SSIS-Dienst keine Chance hat nachzuvollziehen, ob in der Script-Komponenten wirklich eine sinnvolle Operation ausgeführt wird. Durch diese dummy Script-Komponente wird der SSIS-Dienst daran gehindert den Data-Flow zu optimieren.

Um die Zeitmessung zu vereinfachen messen wir einfach die gesamte Laufzeit des SSIS-Paket. Zwar messen wir damit auch den gesamten Overhead des SSIS-Pakets, da wir in allen Tests so verfahren lässt sich diese minimale Ungenauigkeit aber verschmerzen.

Laufzeit des SSIS-Pakets

Laufzeit des SSIS-Pakets

Die Auswertung des ersten Test war in der Tat ernüchternd:

Laufzeitergebnis 1: Script-Komponete

Laufzeitergebnis 1: Script-Komponete

2.4 MB/s ist sehr langsam. Zum Vergleich ersetzten wir die Datenquellen alternativ durch eine CSV Source und durch eine Raw File Source. Das Ergebnis war wie folgt:

Laufzeitergebnisse 2: Script-Komponente, CSV, Raw File

Laufzeitergebnisse 2: Script-Komponente, CSV, Raw File

Damit ist die Script-Komponenten in der Tat die langsamste. Sollte der Kollege am Ende Recht behalten? Da ich mir immer noch nicht vorstellen konnte, dass ein in C# geschriebene Script-Komponenten derart langsam sein sollte, haben wir uns den Quellcode angesehen:

Ursprungs Quellcode

Ursprungs Quellcode

Der Code ist auf den ersten Blick unauffällig. Eine For-Schleife zählt von 1 bis NumberOfRows (1.000.000) hoch und erzeugt die 100-Byte Zeilen. Etwas unglücklich ist, dass die SSIS Variable NumberOfRows innerhalb der for-Schleife jedes Mal aus dem Variablen-Pool ausgelesen wird. Das könnte ein Problem sein, da die Script-Komponenten bei jedem Lesevorgang auf die Variablen des SSIS-Pakets zugreifen muss. Wir schreiben den Code wie folgt um:

Optimierter Variablenzugriff

Optimierter Variablenzugriff

Und Messen erneut:

Laufzeitergebnis 3: Script-Komponente, CSV, Raw File

Laufzeitergebnis 3: Script-Komponente, CSV, Raw File

Mit dieser Kleinigkeit verdreifachen wir die Performance!

Ermutigt durch den großen Erfolg durch eine so einfach Maßnahme schauen wir uns den Inhalt der Schleife genauer an. Wir vermuteten, dass die vielen Converts und Cast verhältnismäßig aufwändig sind und stellen den Code weiter wie folgt um:

Script-Komponente ohne Cast und Converts

Script-Komponente ohne Cast und Converts

Und Messen erneut:

Laufzeitergebnis 4: Script-Komponente, CSV, Raw File

Laufzeitergebnis 4: Script-Komponente, CSV, Raw File

Tja, das war es wohl. Mehr kann man an so einem einfach Code wohl nicht machen. Aber wie teuer ist die Berechnung der Daten in jeder Zeile? Wir bedingen die Zuweisung in der ersten Zeile wie folgt:

Auslagern der Messung

Auslagern der Messung

Und Messen erneut mit und ohne Debug Mode:

Laufzeitergebnis 5 - Script-Komponente alle Varianten, CSV, Raw File

Laufzeitergebnis 5 – Script-Komponente alle Varianten, CSV, Raw File

Fazit:

  • Die Script-Komponenten ist von Hause aus nicht langsam! Zwar hängt die Leistungsfähigkeit noch von vielen weitern Faktoren ab, CPU, Ram, usw. In unserer Testumgebung war die Script-Komponente deutlich schneller als eine CSV Source.
  • Innerhalb von Schleifen sollte man aufpassen, da auch unfällige einfache Operationen die Laufzeit ungünstige beeinflussen können.
  • Die Raw File Source ist mehr als doppelt so schnell wie die CSV Source. Sicher eine gute Alternative für temporäre Zwischenspeicherungen.