Você pode melhorar o desempenho do fluxo de mensagens com o ESQL utilizando algumas técnicas de otimização.
Ao gravar seu código ESQL, é possível usar várias técnicas para melhorar o desempenho de seus fluxos de mensagens. As seções a seguir contêm orientação sobre como melhorar o desempenho de seu código ESQL:
Subscritos de matriz [ ] são caros em termos de desempenho devido à maneira na qual subscript é avaliada dinamicamente no tempo de execução. Por para evitar o uso de subscripts de matriz sempre que possível, você pode melhorar o desempenho de seu código ESQL. Ao invés disso, você pode usar variáveis de referência, que mantêm um ponteiro para a matriz e que pode, então, ser reutilizada; por exemplo:
DECLARE myref REFERENCE TO InputRoot.XML.Invoice.Purchases.Item[1];
-- Continue processing for each item in the array
WHILE LASTMOVE(myref)=TRUE DO
-- Add 1 to each item in the array
SET myref = myref + 1;
-- Do some processing
-- Move the dynamic reference to the next item in the array
MOVE myref NEXTSIBLING;
END WHILE;
Exemplo de processamento de matriz ESQL:
O exemplo a seguir mostra ESQL sendo utilizado para processar registros lidos a partir de um banco de dados. O uso repetido de subscripts de matriz, tais como Environment.Variables.DBData[A] aumenta o tempo de processamento 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;
Você pode reduzir o tempo de processamento significativamente utilizando variáveis de referência
WHILE ( I < CARDINALITY (InputRoot.MRM.A.B.C[]
SET ARRAY_SIZE = CARDINALITY (InputRoot.MRM.A.B.C[]
WHILE ( I < ARRAY_SIZE )
Reduz o número de instruções DECLARE (e, portanto, o custo de desempenho), declarando uma variável e configurando seu valor inicial em uma instrução única. Como alternativa, você pode declarar várias variáveis do mesmo tipo de dados em uma única instrução ESQL em vez de em várias instruções. Esta técnica também ajuda a reduzir o uso de memória.
A instrução do EVAL é, às vezes, usada quando há um requisito para determinar dinamicamente nomes de correlação. No entanto, é cara em termos de utilização de CPU, porque ele envolve a instrução que está sendo executada duas vezes. Na primeira vez que é executada, as partes do componente são determinadas a fim de construir a instrução que será executada, então, a instrução que foi construída é executada.
As técnicas a seguir podem aprimorar significativamente o desempenho quando você está utilizando as instruções PASSTHRU:
Por exemplo, a seguinte instrução possui dois valores de dados e literal: 100 e IBM:
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = 100 WHERE SP.COMPANY = ‘IBM’’);
Esta instrução é efetiva quando o preço é 100 e a empresa é IBM. Quando o Price ou Company é alterado, outra instrução é necessária, com outra instrução PREPARAR do SQL, que impacta o desempenho.
PASSTHRU(’UPDATE SHAREPRICES AS SP SET Price = ? WHERE SP.COMPANY = ?’,
InputRoot.XML.Message.Price,InputRoot.XML.Message.Company);
db2 connect to <database name>
db2 get snapshot for database on <database name>
db2 connect to <database name>
db2 get snapshot for dynamic SQL on <database name>
DECLARE refPtr REFERENCE to InputRoot.XMLNSC.A.B.C.D;
Para acessar o elemento E da árvore de mensagens, utilize o nome de correlação refPtr.E.
Você pode utilizar instruções REFERENCE e MOVE para ajudar a reduzir a quantidade de navegação dentro da árvore de mensagens, o que melhora o desempenho. Essa técnica pode ser útil quando você está construindo um grande número de instruções SET ou CREATE; em vez de navegar para a mesma ramificação na árvore, é possível usar uma variável REFERENCE para estabelecer um ponteiro para a filial e, em seguida, utilize a instrução MOVE para processar um campo de cada vez.
As funções de manipulação de cadeia usadas no ESQL podem ser intensivas do CPU; funções como LENGTH, SUBSTRING, e RTRIM devem acessar bytes individuais na árvore de mensagens. Estas funções são caras em termos de desempenho, então minimizar a sua utilização pode ajudar a melhorar o desempenho. Quandopossível, evite também executar as mesmas concatenações repetidamente por armazenar resultados intermediários em variáveis.
O desempenho pode ser reduzido sob as seguintes condições:
Este problema ocorre quando você utiliza referências de campos, em vez de variáveis de referências, para acessar ou criar campos ou registros consecutivos.
O exemplo a seguir mostra instruções SET independentes utilizando caminhos de referência de campo para manipular a árvore de mensagens. A instrução SET utiliza um parâmetro de origem e um parâmetro de destino, em que um ou ambos os parâmetros são referências de campo:
SET OutputRoot.XMLNS.TestCase.StructureA.ParentA.field = '1';
O desempenho é afetado pela instrução SET que é usada para criar vários campos adicionais, como mostrado no exemplo a seguir:
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';
Nesse exemplo, os cinco campos criados são todos filhos de ParentA. Antes da criação ou modificação do campo especificado, o broker deve navegar na árvore de mensagens nomeada para localizar o ponto na árvore de mensagens que deve ser alterado. Por exemplo:
Navegar por todos os campos que precedem o campo especificado causa perda no desempenho.
DECLARE myChar CHAR;
DECLARE thisRecord INT 0;
WHILE thisRecord < 10000 DO
SET thisRecord = thisRecord + 1;
SET myChar = InputRoot.MRM.myParent.myRepeatingRecord[thisRecord];
END WHILE;
Quando a notação de índice é utilizada, à medida que a contagem aumenta, o processamento precisa navegar por todos os campos precedentes para obter o campo necessário; ele deve contar nos registros anteriores para chegar ao que é representado pela referência indexada atual. Portanto, o número total de navegações para esse loop WHILE é: 1 + 2 + 3 + .... + N, que não é linear.
Se você estiver acessando ou criando campos ou registros consecutivos, você pode resolver esse problema utilizando variáveis de referência.
Quando você utiliza variáveis de referência, a instrução navega até o pai principal, que mantém um ponteiro para o campo na árvore de mensagens. O seguinte exemplo mostra o ESQL que pode ser utilizado para reduzir o número de navegações ao criar novos campos da árvore de mensagens de saída:
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';
Ao referenciar campos da árvore de mensagens de entrada de repetição, você pode utilizar o seguinte ESQL:
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;
Veja informações adicionais na publicação Criando Referências de Campos Dinâmicos.