IBM Integration Bus, Version 9.0.0.7 Operating Systems: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS

See information about the latest product version

Tipps für ESQL-Code

Es gibt einige Möglichkeiten, die Leistung von Nachrichtenflüssen unter Verwendung von ESQL-Code zu optimieren.

Vorbereitungen:

Beim Schreiben von ESQL-Code gibt es verschiedene Möglichkeiten, die Leistung der Nachrichtenflüsse zu verbessern. Hinweise zur Optimierung des ESQL-Codes finden Sie in den folgenden Abschnitten:

ESQL-Array-Verarbeitung

Aufgrund der Art und Weise, wie Array-Subscripts [ ] zur Laufzeit dynamisch ausgewertet werden, sind diese Scripts leistungsintensiv. Sie können die Leistung Ihres ESQL-Codes verbessern, indem Sie die Verwendung von Array-Subscripts nach Möglichkeit vermeiden. Stattdessen können Sie Referenzvariablen verwenden, die einen Verweis auf das Array enthalten und wiederverwendet werden können. Beispiel:

DECLARE myref REFERENCE TO InputRoot.XML.Invoice.Purchases.Item[1];
-- Jedes Element im Array verarbeiten
WHILE LASTMOVE(myref)=TRUE DO
   -- Zu jedem Element im Bereich 1 hinzufügen
   SET myref = myref + 1;
   -- Verarbeitung
   -- Dynamischen Verweis auf nächstes Element im Bereich setzen
   MOVE myref NEXTSIBLING;
END WHILE;

Beispiel für ESQL-Array-Verarbeitung:

Das folgende Beispiel zeigt, wie mithilfe von ESQL aus einer Datenbank gelesene Datensätze verarbeitet werden. Durch die wiederholte Verwendung von Array-Subscripts wie beispielsweise Environment.Variables.DBData[A] wird die Verarbeitungszeit erheblich erhöht:

SET Environment.Variables.DBDATA[] =
(
SELECT T.*
FROM Database.{'ABC'}.{'XYZ'} as T
);

DECLARE A INTEGER 1;
DECLARE B INTEGER CARDINALITY(Environment.Variables.*[]);
SET JPcntFODS = B;
WHILE A <= B DO
            CALL CopyMessageHeaders();
            CREATE FIELD OutputRoot.XML.FODS;
            DECLARE outRootRef REFERENCE TO OutputRoot.XML.Data;

            SET outRootRef.Field1 = Trim(Environment.Variables.DBDATA[A].Field1);
            SET outRootRef.Field2 = Trim(Environment.Variables.DBDATA[A].Field2);
            SET outRootRef.Field3 = Trim(Environment.Variables.DBDATA[A].Field3);
            SET outRootRef.Field4 = Trim(Environment.Variables.DBDATA[A].Field4);
            SET outRootRef.Field5 = Trim(Environment.Variables.DBDATA[A].Field5);
            . . .
            . . .
            SET outRootRef.Field37 = CAST(Environment.Variables.DBDATA[A].Field37)

            SET A = A + 1;
            PROPAGATE;
END WHILE;

Mithilfe von Referenzvariablen können Sie die Verarbeitungszeit erheblich verkürzen.

ESQL-Funktion CARDINALITY

Vermeiden Sie die Verwendung der Funktion CARDINALITY in Schleifen. Beispiel:
WHILE ( I < CARDINALITY (InputRoot.MRM.A.B.C[]
Die Funktion CARDINALITY muss bei jedem Durchlaufen der Schleife ausgewertet werden, was sich nachteilig auf die Leistung auswirkt. Dies gilt vor allem für große Arrays, da die Schleife hier öfter wiederholt wird. Es ist sinnvoller, vor der WHILE-Schleife die Größe des Arrays zu ermitteln (sofern diese sich nicht innerhalb der Schleife ändert), damit nur einmal eine Validierung erfolgt. Beispiel:
SET ARRAY_SIZE = CARDINALITY (InputRoot.MRM.A.B.C[]
WHILE ( I < ARRAY_SIZE )

ESQL-Anweisungen DECLARE und EVAL

Sie können die Anzahl der Anweisungen DECLARE verringern (und somit die Leistung verbessern), indem Sie in einer einzigen Anweisung eine Variable deklarieren und ihren Ausgangswert setzen. Alternativ dazu können Sie mehrere Variablen desselben Datentyps in einer einzigen ESQL-Anweisung anstatt in mehreren Anweisungen deklarieren. Auf diese Weise lässt sich auch die Speicherbelegung reduzieren.

Die Anweisung EVAL wird hin und wieder verwendet, wenn Korrelationsnamen dynamisch ermittelt werden müssen. Dies führt jedoch zu einer hohen CPU-Auslastung, da die Anweisung zweimal ausgeführt werden muss. Bei der ersten Ausführung werden die einzelnen Komponenten ermittelt, um die auszuführende Anweisung zu erstellen; anschließend wird diese Anweisung ausgeführt.

ESQL-Anweisung PASSTHRU

Bei Verwendung von Anweisungen PASSTHRU kann die Leistung mit den folgenden Verfahren erheblich verbessert werden:

  • Vermeiden Sie die gemeinsame Verwendung der Anweisungen PASSTHRU und CALL, um eine gespeicherte Prozedur aufzurufen. Stattdessen können Sie die Befehle CREATE PROCEDURE ... EXTERNAL ... und CALL ... verwenden.
  • Verwenden Sie bei SQL-Anweisungen, für die Literal- oder Datenwerte erforderlich sind, Hostvariablen, die einer Variablen einen Spaltenwert zuordnen. Dadurch können dynamische SQL-Anweisungen in der Datenbank wiederverwendet werden. Die Verwendung von SQL PREPARE in einer dynamischen Anweisung wirkt sich nachteilig auf die Leistung aus; daher ist es sinnvoller, diese Anweisung nur einmal und anschließend mehrmals die Anweisung EXECUTE auszuführen, als jedes Mal die Anweisungen PREPARE und EXECUTE auszuführen.

Die folgende Anweisung umfasst beispielsweise zwei Daten- und Literalwerte, 100 und IBM:

PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = 100 WHERE SP.COMPANY = ‘IBM’’);

Diese Anweisung ist effektiv, wenn der Preis 100 beträgt und es sich bei dem Unternehmen um IBM handelt. Wenn sich der Preis oder das Unternehmen ändert, ist eine andere Anweisung mit einer anderen SQL-Anweisung PREPARE erforderlich, was sich nachteilig auf die Leistung auswirkt.

Bei Verwendung der folgenden Anweisung hingegen ist auch bei Änderungen am Preis oder am Unternehmen keine andere Anweisung bzw. Anweisung PREPARE erforderlich:
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = ? WHERE SP.COMPANY = ?’,
InputRoot.XML.Message.Price,InputRoot.XML.Message.Company);
Sie können überprüfen, ob mit dem dynamischen SQL-Code eine maximale Wiederverwendung von Anweisungen erreicht wird, indem Sie mithilfe der folgenden Befehle den Inhalt des SQL-Anweisungscache in DB2 anzeigen:
db2 connect to <Datenbankname>
db2 get snapshot for database on <Datenbankname>
Mit den folgenden Befehlen können Sie den Inhalt des Cache für dynamische Anweisungen anzeigen:
db2 connect to <Datenbankname>
db2 get snapshot for dynamic SQL on <Datenbankname>

ESQL-Referenzvariablen

Mithilfe von Referenzvariablen können Sie auf lange Korrelationsnamen wie InputRoot.XMLNSC.A.B.C.D.E verweisen. Dazu müssen Sie einen Referenzzeiger deklarieren, wie im folgenden Beispiel dargestellt:
DECLARE refPtr REFERENCE to InputRoot.XMLNSC.A.B.C.D;

Auf Element 'E' der Nachrichtenbaumstruktur kann mit dem Korrelationsnamen refPtr.E. zugegriffen werden.

Mit Anweisungen REFERENCE und MOVE können Sie die Navigation innerhalb der Nachrichtenbaumstruktur vereinfachen und damit die Leistung verbessern. Dies ist hilfreich, wenn Sie eine Vielzahl von Anweisungen SET oder CREATE erstellen; anstatt zu dem Zweig in der Struktur zu navigieren, können Sie mithilfe einer Variablen REFERENCE einen Zeiger auf diesen Zweig erstellen und anschließend mit der Anweisung MOVE die Felder nacheinander verarbeiten.

ESQL-Zeichenfolgefunktionen

In ESQL verwendete Funktionen zur Bearbeitung von Zeichenfolgen können zu einer hohen CPU-Auslastung führen; mit Funktionen wie LENGTH, SUBSTRING und RTRIM muss auf einzelne Bytes in der Nachrichtenbaumstruktur zugegriffen werden. Diese Funktionen wirken sich erheblich auf die Leistung aus; daher kann die Leistung verbessert werden, wenn sie so wenig wie möglich verwendet werden. Nach Möglichkeit sollten Sie auch die wiederholte Ausführung ein und derselben Verkettung vermeiden, indem Sie Zwischenergebnisse in Variablen speichern.

Nachrichtenbaumstrukturen mit sich wiederholenden Datensätzen

Die Leistung kann in den folgenden Fällen beeinträchtigt sein:

  • Mit ESQL-Verarbeitung werden umfangreiche Nachrichtenbaumstrukturen bearbeitet.
  • Die Nachrichtenbaumstruktur besteht aus sich wiederholenden Datensätzen oder vielen Feldern.
  • Mithilfe expliziter Anweisungen SET mit Feldreferenzpfaden wurde auf Felder zugegriffen bzw. auf diese Weise wurden Felder erstellt.
  • Es kommt zu einer allmählichen Verlangsamung bei der Nachrichtenflussverarbeitung, da von ESQL mehr Felder oder Wiederholungen verarbeitet werden.

Dieses Problem tritt auf, wenn Sie mithilfe von Feldreferenzen und nicht mittels Referenzvariablen auf aufeinanderfolgende Felder oder Datensätze zugreifen bzw. diese erstellen.

Im folgenden Beispiel sind unabhängige Anweisungen SET dargestellt, in denen Feldreferenzpfade zur Bearbeitung der Nachrichtenbaumstruktur verwendet werden. Die Anweisung SET umfasst einen Quellen- und Zielparameter, wobei ein oder beide Parameter Feldverweise sind:

SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field = '1';

Wenn mit der Anweisung SET eine Vielzahl weiterer Felder erstellt wird, wirkt sich dies auf die Leistung aus, wie im folgenden Beispiel dargestellt:

SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field1 = '1';
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field2 = '2';
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field3 = '3';
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field4 = '4';
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field5 = '5';

In diesem Beispiel sind alle fünf erstellten Felder 'ParentA' untergeordnet. Bevor das angegebene Feld erstellt oder geändert werden kann, muss der Broker die benannte Nachrichtenbaumstruktur durchsuchen, um dort den Punkt zu finden, der geändert werden muss. Beispiele:

  • Für den Zugriff auf Feld 1 navigiert die Anweisung SET zu 'ParentA' und anschließend zum ersten Feld, d. h., es sind zwei Navigationsvorgänge erforderlich.
  • Für den Zugriff auf Feld 5 navigiert die Anweisung SET zu 'ParentA'; anschließend durchläuft sie alle vorherigen Felder, bis sie schließlich Feld 5 erreicht, es sind also sechs Navigationsvorgänge erforderlich.

Das Navigieren zu allen Feldern, die dem angegebenen Feld vorausgehen, führt letztlich zum Leistungsverlust.

Das folgende Beispiel zeigt, wie auf sich wiederholende Felder in einer Eingabenachrichtenstruktur zugegriffen wird:
DECLARE myChar CHAR;
DECLARE thisRecord INT 0;
WHILE thisRecord < 10000 DO
		SET thisRecord = thisRecord + 1;
		SET myChar = InputRoot.MRM.myParent.myRepeatingRecord[thisRecord];
END WHILE;  
Bei Verwendung der Indexschreibweise müssen, wenn der Zähler erhöht wird, bei der Verarbeitung alle vorherigen Felder durchlaufen werden, um zu dem jeweiligen Feld zu gelangen, es müssen also alle vorherigen Datensätze abgezählt werden, um zu dem Datensatz zu gelangen, der durch den aktuellen indexierten Verweis dargestellt wird.
  • Beim Zugriff auf 'InputRoot.MRM.myParent.myRepeatingRecord[1]' erfolgt ein Navigationsvorgang, um zum ersten Datensatz zu gelangen.
  • Beim Zugriff auf 'InputRoot.MRM.myParent.myRepeatingRecord[2]' erfolgen zwei Navigationsvorgänge, um zum zweiten Datensatz zu gelangen.
  • Beim Zugriff auf 'InputRoot.MRM.myParent.myRepeatingRecord[N]' erfolgen n Navigationsvorgänge, um zum n-ten Datensatz zu gelangen.

Aus diesem Grund beträgt die Gesamtzahl an Navigationen für diese WHILE-Schleife: 1 + 2 + 3 + .... + N (nicht linear).

Wenn Sie auf aufeinanderfolgende Felder oder Datensätze zugreifen bzw. aufeinanderfolgende Felder oder Datensätze erstellen, können Sie dieses Problem durch Verwendung von Referenzvariablen lösen.

Wenn Sie Sie Referenzvariablen verwenden, navigiert die Anweisung zum übergeordneten Hauptelement, das einen Zeiger zum Feld in der Nachrichtenbaumstruktur verwaltet. Im folgenden Beispiel wird das ESQL gezeigt, mit dem die Anzahl an Navigationsschritten beim Erstellen neuer Ausgabenachricht-Baumstrukturfelder reduziert wird:

SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field1 = '1';
DECLARE outRef REFERENCE TO OutputRoot.XMLNS.TestCase.StructureA.ParentA;
SET outRef.field2 = '2';
SET outRef.field3 = '3';
SET outRef.field4 = '4';
SET outRef.field5 = '5';

Mit dem folgenden ESQL-Code können Sie auf sich wiederholende Felder in einer Eingabenachrichtenstruktur verweisen:

DECLARE myChar CHAR;
DECLARE inputRef REFERENCE TO InputRoot.MRM.myParent.myRepeatingRecord[1];
WHILE LASTMOVE(inputRef) DO
		SET myChar = inputRef;
		MOVE inputRef NEXTSIBLING NAME 'myRepeatingRecord';
END WHILE;

Weitere Informationen hierzu finden Sie im Abschnitt Dynamische Feldverweise erstellen.


bj28653_.htm | Letzte Aktualisierung Monday, 27 March 2017