Puede mejorar el rendimiento del flujo de mensajes con ESQL utilizando algunas técnicas de optimización.
Al escribir el código ESQL, puede utilizar varias técnicas para mejorar el rendimiento de los flujos de mensajes. Las secciones siguientes contienen instrucciones sobre cómo mejorar el rendimiento de su código ESQL:
Los subíndices de matriz [ ] son caros en términos de rendimiento debido a la forma en que se evalúa el subíndice dinámicamente en tiempo de ejecución. Al evitar el uso de subíndices de matriz siempre que sea posible, puede mejorar el rendimiento de su código ESQL. En su lugar puede utilizar variables de referencia, que mantienen un puntero en la matriz y que pueden volver a utilizarse a continuación; por ejemplo:
DECLARE myref REFERENCE TO InputRoot.XML.Invoice.Purchases.Item[1];
-- Continuar el proceso para cada elemento de la matriz
WHILE LASTMOVE(myref)=TRUE DO
-- Añadir 1 a cada elemento de la matriz
SET myref = myref + 1;
-- Realizar algún proceso
-- Mover la referencia dinámica al siguiente elemento de la matriz
MOVE myref NEXTSIBLING;
END WHILE;
Ejemplo de proceso de matriz ESQL:
El ejemplo siguiente muestra cómo se utiliza ESQL para procesar registros leídos de una base de datos. El uso repetido de subíndices de matriz como Environment.Variables.DBData[A] aumenta el tiempo de proceso significativamente:
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;
Puede reducir el tiempo de proceso significativamente utilizando variables de referencia
WHILE ( I < CARDINALITY (InputRoot.MRM.A.B.C[]
SET ARRAY_SIZE = CARDINALITY (InputRoot.MRM.A.B.C[]
WHILE ( I < ARRAY_SIZE )
Reduzca el número de sentencias DECLARE (y, por consiguiente, el coste de rendimiento) declarando una variable y estableciendo su valor inicial en una sola sentencia. De forma alternativa, puede declarar varias variables del mismo tipo de datos dentro de una sola sentencia ESQL en lugar de varias sentencias. Esta técnica también ayuda a reducir el uso de memoria.
La sentencia EVAL se utiliza a veces cuando existe el requisito de determinar dinámicamente los nombres de correlación. Sin embargo, es caro en términos de uso de CPU, porque implica que la sentencia se ejecuta dos veces. La primera vez que se ejecuta, los componentes están determinados, a fin de construir la sentencia que se va a ejecutar; luego se ejecuta la sentencia que se ha construido.
Las técnicas siguientes pueden mejorar significativamente el rendimiento cuando se utilizan sentencias PASSTHRU:
Por ejemplo, la sentencia siguiente tiene dos valores de datos y literales, 100 e IBM:
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = 100 WHERE SP.COMPANY = ‘IBM’’);
Esta sentencia entra en vigor cuando el precio es 100 y la empresa es IBM. Cuando el valor de Price o Company cambia, otra sentencia es necesaria, con otra sentencia SQL PREPARE, que afecte al rendimiento.
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = ? WHERE SP.COMPANY = ?’,
InputRoot.XML.Message.Price,InputRoot.XML.Message.Company);
db2 connect to <nombre_base_datos>
db2 get snapshot for database on <nombre_base_datos>
db2 connect to <nombre_base_datos>
db2 get snapshot for dynamic SQL on <nombre_base_datos>
DECLARE refPtr REFERENCE to InputRoot.XMLNSC.A.B.C.D;
Para acceder al elemento E del árbol de mensajes, utilice el nombre de correlación refPtr.E.
Puede utilizar las sentencias REFERENCE y MOVE para ayudarle a reducir la cantidad de navegación en l árbol de mensajes, lo que mejora el rendimiento. Esta técnica puede ser útil cuando se crea un gran número de sentencias SET o CREATE; en lugar de navegar a la misma rama del árbol, puede utilizar una variable REFERENCE para establecer un puntero a la rama y luego utilizar la sentencia MOVE para procesar un campo a la vez.
Las funciones de manipulación de series utilizadas en ESQL pueden hacer un uso intensivo de la CPU; funciones tales como LENGTH, SUBSTRING y RTRIM deben acceder a bytes individuales en el árbol de mensajes. Estas funciones son costosas en términos de rendimiento, por lo que minimizar su uso puede ayudar a mejorar el rendimiento. Siempre que sea posible, evite también la ejecución de las mismas concatenaciones de forma repetida, almacenando los resultados intermedios en variables.
El rendimiento se puede reducir bajo las condiciones siguientes:
Este problema se produce cuando utiliza referencias de campo, en vez de variables de referencia, para acceder o crear campos o registros consecutivos.
El ejemplo siguiente muestra sentencias SET independientes que utilizan vías de acceso de referencia de campo para manipular el árbol de mensajes. La sentencia SET acepta un parámetro de origen y de destino, donde uno o ambos parámetros son referencias de campo:
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field = '1';
El rendimiento se ve afectado al utilizar la sentencia SET para crear muchos más campos, tal como se muestra en el ejemplo siguiente:
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';
En este ejemplo, los cinco campos que se crean son todos hijos de ParentA. Antes de poder crear o modificar el campo especificado, el intermediario debe navegar por el árbol de mensaje nombrado para localizar el punto del árbol de mensaje que se ha de alterar. Por ejemplo:
Navegar por todos los campos que preceden al campo especificado provoca la pérdida de rendimiento.
DECLARE myChar CHAR;
DECLARE thisRecord INT 0;
WHILE thisRecord < 10000 DO
SET thisRecord = thisRecord + 1;
SET myChar = InputRoot.MRM.myParent.myRepeatingRecord[thisRecord];
END WHILE;
Cuando se utiliza notación índice, a medida
que el número aumenta, el proceso necesita navegar por todos los
campos precedentes para obtener el campo necesario; tiene
que
volver a contar los registros anteriores para llegar al que está
representado por la referencia indexada actual. Por lo tanto, el número total de navegaciones para este bucle WHILE es: 1 + 2 + 3 + .... + N, que no es lineal.
Si está accediendo a campos o registros consecutivos o está creándolos, puede solucionar este problema utilizando variables de referencia.
Cuando utiliza variables de referencia, la sentencia navega al padre principal, que mantiene un puntero al campo en el árbol de mensaje. El ejemplo siguiente muestra el ESQL que puede utilizarse para reducir el número de navegaciones al crear nuevos campos de árbol de mensaje de salida:
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';
Al hacer referencia a campos de árbol de mensaje de entrada, puede utilizar el ESQL siguiente:
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;
Para obtener información adicional, consulte la tarea Creación de referencias de campo dinámicas.