WebSphere Message Broker, Versión 8.0.0.5 Sistemas operativos: AIX, HP-Itanium, Linux, Solaris, Windows, z/OS

Consulte la información sobre la última versión del producto en IBM Integration Bus, Versión 9.0

Consejos para el código ESQL

Puede mejorar el rendimiento del flujo de mensajes con ESQL utilizando algunas técnicas de optimización.

Antes de empezar:

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:

Proceso de matriz 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

Función CARDINALITY de ESQL

Evite el uso de CARDINALITY en un bucle; por ejemplo:
WHILE ( I < CARDINALITY (InputRoot.MRM.A.B.C[]
La función CARDINALITY debe evaluarse cada vez que se recorre el bucle, lo que es costoso en términos de rendimiento. Esto es particularmente cierto con matrices grandes debido a que el bucle se repite con más frecuencia. Es más eficaz determinar el tamaño de la matriz antes del bucle WHILE (a menos que cambie en el bucle) que se evalúa sólo una vez; por ejemplo:
SET ARRAY_SIZE = CARDINALITY (InputRoot.MRM.A.B.C[]
WHILE ( I < ARRAY_SIZE )

Sentencias de ESQL DECLARE y EVAL

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.

Sentencia de ESQL PASSTHRU

Las técnicas siguientes pueden mejorar significativamente el rendimiento cuando se utilizan sentencias PASSTHRU:

  • Evite el uso de la sentencia PASSTHRU con una sentencia CALL para invocar un procedimiento almacenado. Como alternativa, puede utilizar los mandatos CREATE PROCEDURE ... EXTERNAL ... y CALL ....
  • Cuando trabaje con sentencias SQL que requieren valores de literales o datos, utilice variables host, que correlacionan un valor de columna con una variable. Esto permite que las sentencias de SQL dinámico se vuelvan a utilizar dentro de la base de datos. Una sentencia PREPARE de SQL en una sentencia dinámica es una operación costosa en términos de rendimiento, por lo tanto, resulta más eficaz ejecutarlo sólo una vez y luego aplicar EXECUTE en la sentencia varias veces, en lugar de PREPARE y EXECUTE cada vez.

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.

Sin embargo, al utilizar la sentencia siguiente, Price y Company pueden cambiar sin necesitar otra sentencia u otra PREPARE:
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = ? WHERE SP.COMPANY = ?’,
InputRoot.XML.Message.Price,InputRoot.XML.Message.Company);
Puede comprobar que el SQL dinámico está logrando la reutilización máxima de las sentencias, utilizando los mandatos siguientes para visualizar el contenido de la memoria caché de sentencias SQL en DB2:
db2 connect to <nombre_base_datos>
db2 get snapshot for database on <nombre_base_datos>
Utilice los mandatos siguientes para ver el contenido de la memoria caché de sentencias dinámicas:
db2 connect to <nombre_base_datos>
db2 get snapshot for dynamic SQL on <nombre_base_datos>

Variables de referencia ESQL

Puede utilizar variables de referencia para hacer referencia a nombres de correlación largos como InputRoot.XMLNSC.A.B.C.D.E. Declare un puntero de referencia tal como se muestra en el ejemplo siguiente:
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.

Funciones de serie ESQL

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.

Árboles de mensajes con registros de repetición

El rendimiento se puede reducir bajo las condiciones siguientes:

  • Está utilizando el proceso ESQL para manipular un árbol de mensajes grande
  • El árbol de mensajes consta de registros repetitivos o de muchos campos.
  • Ha utilizado sentencias SET explícitas con vías de acceso de referencia de campo para acceder a los campos o crearlos
  • Ha observado una ralentización gradual del proceso de flujo de mensajes a medida que el ESQL procesa más campos o repeticiones

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:

  • Para acceder al campo 1, la sentencia SET navega a ParentA y luego al primer campo, lo que implica dos navegaciones.
  • Para acceder al campo 5, la sentencia SET navega a ParentA, luego recorre cada uno de los campos precedentes hasta que llega al campo 5, lo que implica seis navegaciones.

Navegar por todos los campos que preceden al campo especificado provoca la pérdida de rendimiento.

El ejemplo siguiente muestra que se accede a campos repetitivos en un árbol de mensajes de entrada:
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.
  • Al acceder a InputRoot.MRM.myParent.myRepeatingRecord[1], tiene lugar una navegación para ir al primer registro
  • Al acceder a InputRoot.MRM.myParent.myRepeatingRecord[2], tienen lugar dos navegaciones para ir al segundo registro
  • Al acceder a InputRoot.MRM.myParent.myRepeatingRecord[N], tienen lugar N navegaciones para ir al enésimo registro

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.

Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Comentarios

Copyright IBM Corporation 1999, 2014Copyright IBM Corporation 1999, 2014.

        
        Última actualización:
        
        Última actualización: 2015-02-28 17:01:26


Tema de tareaTema de tarea | Versión 8.0.0.5 | bj28653_