Otimização de Desempenho do Aplicativo

Apresentação

Em geral, com aplicativos QlikView de pequeno ou médio porte não é necessário se preocupar muito com o desenho do aplicativo em termos de desempenho. À medida que a quantidade de dados aumenta, restrições de tempo e memória podem tornar-se muito evidentes se o aplicativo foi projetado de forma deficiente. É possível que algumas alterações simples no projeto aumentem o desempenho de forma considerável. Este apêndice aponta algumas falhas e sugere soluções para elas.

Em geral, o desempenho é melhorado movendo o "problema" dos objetos de aplicativo para a base de dados orientada por script. Muitas vezes, essa é uma situação de compensação. O tempo de resposta é melhorado e a capacidade ad hoc é diminuída. As recomendações a seguir não devem ser vistas como universalmente benéficas. Use-as quando elas melhorarem o estado geral do aplicativo ou quando fizerem aquela pequena diferença que é decisiva.

A seguir está uma lista de exemplos de métodos aplicados para o tratamento dos problemas citados acima. Eles servem para ilustrar o problema e indicar a funcionalidade útil do QlikView. Não é possível dar uma recomendação geral de qual é o método mais apropriado, mas a ordem dos exemplos é uma indicação.

If ( Condition(Text),....)

Cláusulas If envolvendo comparações de texto são geralmente caras. As soluções podem ser mapear texto para números, por exemplo, usando autonumber (consulte os exemplos na seção anterior) e/ou executar o teste no script.

O teste de caracteres de texto é mais lento do que o teste numérico. Considere a expressão

If (Alfa= ‘ABC’, ‘ABC’, left (Alfa, 2))

Não foi possível executar o teste diretamente no script sem perder flexibilidade.

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

A expressão torna-se

If ( Flag = 1,’ABC’, left (Alfa, 2))

e o teste fica muito mais simples.

Sum ( If (Condition, ‘FieldName’…))

Aqui, a agregação é independente das dimensões da tabela e o resultado é distribuído sobre as dimensões da tabela. O problema pode ser tratado executando o teste no script e agregando na tabela ou realizando toda a operação no script. Existem várias técnicas para isso, por exemplo, interval match, group by, peek, if....then....else.

Este caso envolve dois passos, ou seja, o teste da "Condição " e a agregação do resultado. Se considerarmos o exemplo anterior e incluirmos a agregação

Sum ( If (Alfa= ‘ABC’, Num*1.25 , Num) )

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

A expressão torna-se

Sum ( If ( Flag = 1, Num* 1.25 , Num ) )

A agregação também pode ser realizada diretamente no script, como a seguir:

table_2:

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

table_3:

Load

Alfa,

If ( Flag = 1, Num* 1.25 , Num ) as NewNum

resident table_2 ;

 

table_4:

Load

Alfa,

Sum( NewNum ) as SumNum

resident table_3

group by Alfa ;

Nota: A agregação é feita sobre Alfa já que essa é a dimensão no teste.

If ( Condition, Sum(‘FieldName’)..)

Essa construção é incluída aqui apenas para enfatizar a diferença com relação ao caso anterior. Essa agregação é completamente contextual e, de modo geral, não causa problemas de desempenho.

If ( Condition1, Sum(‘FieldName’), If (Condition2, Sum(‘FieldName’)……..

A lógica de If...then else... aninhada é conceitualmente fácil, mas, às vezes, pode tornar-se difícil de administrar. Nós já vimos casos com centenas de níveis aninhados e eles demandam tanto da memória quando da CPU. Em geral, as "Condições" podem ser substituídas ao transformá-las. Um típico exemplo é agregando quantity*price, em que price é variável. Isso pode ser realizado pela "correspondência de intervalo estendido". Se for necessário que duas condições, por exemplo, “A AND B”, sejam atendidas, o teste pode ser substituído por uma condição “C”.

Exemplo:

sum((GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY)

Replaces

Sum(

If((GAC12_EFCT_DT<= GIV23_REJ_DT and

GAC12_EXPIRE_DT>GIV23_REJ_DT) and

(GAC15_EFCT_DT<= GIV23_REJ_DT and GAC15_EXPIRE_DT>GIV23_REJ_DT),

GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null()))

and

Sum(

If(GAC12_EFCT_DT<= GIV23_REJ_DT,

If(GAC12_EXPIRE_DT>GIV23_REJ_DT,

If(GAC15_EFCT_DT<= GIV23_REJ_DT,

If(GAC15_EXPIRE_DT>GIV23_REJ_DT,

(GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null())))))

ao ler os campos GAC12_STD_COST e GAC15_EXCHANGE_RATE como dimensões de alteração lenta.

Consulte: Usando a sintaxe intervalmatch estendida para resolver problemas de lentidão durante a alteração de dimensões

Classificando o Texto

O QlikView avalia automaticamente se um Campo deve ser tratado como numérico, texto ou geral. Os campos avaliados como texto serão classificados como texto, o que equivale à operação de classificação mais baixa. Ela pode ser substituída manualmente pela classificação por ordem de carga. Se a classificação de listas etc, não for necessária, desative-a.

O QlikView classifica caracteres de caracteres misturados e números em ordem alfanumérica. Ou seja, os números são classificados na ordem de valor, enquanto os itens que não são numéricos são classificados na ordem ASCII, em oposição a ordem de classificação tradicional ASCII apenas. Exemplo:

Classificação ASCII Classificação alfanumérica
A1 A1
A10 A4
A11 A5
A30 A6
A4 A10
A5 A11
A6 A30

Títulos Dinâmicos e Objetos de Texto

Expressões dinamicamente calculadas podem ser inseridas em quase todos os lugares onde é possível inserir texto. Os recursos necessários para a avaliação de uma expressão dependem, no entanto, do ambiente. As expressões nos gráficos e nas tabelas, definidas na caixa de diálogo de expressões, serão calculadas somente quando o objeto estiver visível e os dados forem alterados. Por exemplo, elas serão calculadas quando o objeto for minimizado.

Por outro lado, se o título do objeto for calculado, esse cálculo será realizado sempre que qualquer alteração ocorrer. Há também várias maneiras de definir condições de exibição, condições de cálculo, etc. Esses testes também serão realizados todas as vezes.

Algumas expressões são mais caras do que outras e, quanto mais elas tiverem que ser avaliadas, tornam-se ainda mais caras. A introdução do cálculo assíncrono teve seu comportamento alterado e, talvez, esse efeito tenha se tornado mais perceptível em seus aplicativos.

As funções de tempo, por exemplo, Now() e Today() serão avaliadas sempre que um recálculo for necessário. A função Now() particularmente pode tornar-se um tanto quanto custosa, uma vez que ela gera um recálculo do aplicativo a cada segundo.

Por exemplo:

If ( ReloadTime()+3>Now(), 'Old Data', 'New Data')

Aqui, podemos considerar

If ( ReloadTime()+3>Today(), 'Old Data', 'New Data')

Como um simples teste, coloque as expressões em caixas de texto. Em seguida, tente dimensionar a caixa de texto com Now() dentro dela.

Disparadores de Macro ("na alteração")

As macros podem ser disparadas por quase todos os eventos que ocorrem no aplicativo. Cuidado com os eventos em cascata ou recursivos, já que um evento dispara o próximo da vez.