Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Sempre assumi como "dogma" que um pré-load é a maneira mais indicada de executar a parte de transformação em um script QlikView.
Havia lido esse artigo Preceding Load e sempre tomei como certo que um código como o abaixo é a melhor saída:
LOAD *,
Dim1 & Dim2 as Dim4,
Expression1 + Expression2 as Expression4;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3
FROM Transactions.qvd(qvd);
Quando me deparo com essa leitura do rwunderlich The Cost of Preceding Load | Qlikview Cookbook.
Nota: se você nunca ouviu falar do Rob Wunderlich, você não sabe nada de Qlik, acredite.
Resolvi então fazer meus testes em grandes volumes e testar a hipótese de uma carga precedente (carinhosamente "pre load") ser mais ineficiente.
Fiz um teste da seguinte maneira.
Gerando um QVD com 10.000.000 de registros
trace Gerando QVD para testes;
Transactions:
Load
TransLineID,
TransID,
mod(TransID,26)+1 as Num,
Pick(Ceil(3*Rand1),'A','B','C') as Dim1,
Pick(Ceil(6*Rand1),'a','b','c','d','e','f') as Dim2,
Pick(Ceil(3*Rand()),'X','Y','Z') as Dim3,
Round(1000*Rand()*Rand()*Rand1) as Expression1,
Round( 10*Rand()*Rand()*Rand1) as Expression2,
Round(Rand()*Rand1,0.00001) as Expression3;
Load
Rand() as Rand1,
IterNo() as TransLineID,
RecNo() as TransID
Autogenerate 10000000;
Store Transactions into Transactions.qvd(qvd);
drop Table Transactions;
Fazendo leitura otimizada do QVD e medindo o tempo
LET t1=now();
trace Leitura Otimizada;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3
FROM Transactions.qvd(qvd);
Let t1=interval(now() - t1);
drop Table Transactions;
Fazendo leitura não otimizada do QVD e medindo o tempo
LET t2=now();
trace Leitura Otimizada;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3,
null() as X // forcando leitura nao otimizada
FROM Transactions.qvd(qvd);
Let t2=interval(now() - t2);
drop Table Transactions;
Fazendo 1 Pré Load
LET t3=now();
trace Lendo com 1 pre-load;
LOAD *,
Dim1 & Dim2 as Dim4,
Expression1 + Expression2 as Expressio4;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3
FROM Transactions.qvd(qvd);
Let t3=interval(now() - t3);
drop Table Transactions;
Fazendo 2 Pré Load
LET t4=now();
trace Lendo com 2 pre-load;
LOAD *,
Dim1 & Dim2 as Dim5,
Expression1 + Expression4 as Expression5;
LOAD *,
Dim1 & Dim2 as Dim4,
Expression1 + Expression2 as Expression4;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3
FROM Transactions.qvd(qvd);
Let t4=interval(now() - t4);
drop Table Transactions;
Fazendo leitura e posterior leitura residente
LET t5=now();
trace Leitura otimizada;
LOAD TransLineID,
TransID,
Num,
Dim1,
Dim2,
Dim3,
Expression1,
Expression2,
Expression3,
null() as X // forcando leitura nao otimizada
FROM Transactions.qvd(qvd);
trace Load Resident;
left join (Transactions)
LOAD TransID,
Dim1 & Dim2 as Dim4,
Expression1 + Expression2 as Expression4
resident Transactions;
Let t5=interval(now() - t5);
drop Table Transactions;
Comparando os resultados cheguei a esses números:
Uma leitura não otimizada x otimizada eu já esperava um aumento grande, é o normal do Qlik.
Mas eu esperava que um pré-load não impactasse tanto a performance. Pude ver um aumento de 290% sobre uma leitura não otimizada. Ou seja o pré-load piorou a performance 3x! Quando um segundo nível de pré-load foi adicionado as coisas ficaram ainda piores chegando a 4x o tempo de uma leitura não otimizada.
Como referência, fazendo-se uma leitura não otimizada e depois um resident adicionou apenas 70% ao tempo de execução.
Conclusão: Teste seu script usando pré-load e resident. Fatores como quantidade de registros, quantidade de cálculos, complexidade dos cálculos impactam na decisão de qual estratégica usar em sua aplicação.
Abraços, enjoy Qliking
Clever,
Muito bom! Nunca havia parado para pensar e analisar que poderia ter tamanha diferença de performance.
Não sei se ocorre mudanças também, mas ao invés de fazer a leitura resident, criar um qvd e ler novamente o arquivo.
Abs
Fabio Nakashigue
Bom dia Clever
Eu já vinha "desconfiando" disso nas últimas semanas, e o post do "homem do chapéu" somente confirmou as minhas suspeitas.
Já faz algum tempo que identificamos esse comportamento no Qlikview. De lá para cá temos adotado exatamente a abordagem que você sugere: análise (registros, cálculos) para definir a melhor estratégia.
Obrigado pela postagem.
Fábio
Fiz esse teste também, e depende muito do caso. Em alguns casos vale a pena; em outros o tempo não varia em relação a leitura via Resident.
Clever, abordei este tópico dentro do meu tema no QlikDevGroup no Rio e em São Paulo. No exemplo que mostrei o tempo de processamento foi de 5 minutos para 20 segundos.....
Parabéns pelo post.
Márcio,
Acredito que o caso do resident para algumas coisas realmente valem a pena. Mas lembrando que existe limite de registros lidos para resident, sendo assim para base com muitos registros é melhor e mais garantido gerar um qvd novo.
Abs.
Fabio Nakashigue
Clever,
abordei este tópico dentro do meu tema no QlikDevGroup no Rio e em São Paulo. No exemplo que mostrei o tempo de processamento caiu de 5 minutos para 20 segundos. Da uma grande diferença..
Parabéns pelo post.
Bom dia Fábio.
Até hoje não esbarrei em limitação de leitura via Resident.
Qual é o limite de registros?
Abs
" existe limite de registros lidos para resident" desconheço também se existe limitação.
No meu exemplo fiz um residente com 10.000.000 e rodou "fino"
Bom dia Fábio.
Eu também até hoje não esbarrei em limitação de leitura via Resident, bom saber que existe!
Bacana seu teste e o cara do chapéu realmente é uma lenda !
Abs