Melhores Práticas – Concatenar tabelas sem perder a leitura otimizada

Fala pessoal, beleza?

 

Acredito que muitos aqui já elaboraram um belíssimo código seguinte todos a maioria das melhores práticas em script/modelagem e precisaram concatenar (Concatenate) duas ou mais tabelas (fatos ou não), porém essa concatenação esta demorando muito tempo para ocorrer. Já passaram por isso?

Esse artigo explicará como realizar a concatenação de tabelas mantendo uma leitura otimizada. Vamos la?

 

Continuar lendo

Melhores Práticas – Formatação de campos sem perder a leitura otimizada

Fala pessoal, tudo bom?

 

Provavelmente em algum momento você já teve que carregar uma tabela fato grande e notou que alguns campos numéricos e datas não vieram formatados da forma em que precisa para exibi-los e utiliza-los em suas expressões, nossa primeira reação é de adicionar as funções de formatação no script de leitura deste QVD, mas logo percebemos que a leitura que antes ocorria em 20 segundos passou a demorar mais de 10 minutos por que perdemos a leitura otimizada do QVD.

 

Continuar lendo

Melhores Práticas – ApplyMap

Fala pessoal, tudo bom?

 

Quero continuar comentando sobre melhores práticas para QlikView e neste capítulo vou falar um pouco sobre a função Applymap.

 

A função Applymap é nada mais, nada menos do que um De-Para, ou seja, substitui um valor por outro através de uma tabela de mapeamento.

Por que um de-para pode ser considerado uma melhor prática de desenvolvimento? Pois essa função, na maioria dos casos, pode ser utilizada para substituir a função JOIN com uma performance MUITO MAIOR. Lembrando que estamos falando no desempenho da execução de carga.
 
 
 

Explicação para utilização

  • Deve-se declarar uma tabela de mapeamento através da função Mapping;
  • A tabela de mapeamento deve conter apenas duas colunas;
  • A primeira coluna é sempre o De e segunda coluna sempre o Para;
  • A utilização deve ocorrer somente no método 1:1 (um para um);
  • Os nomes das colunas na tabela de mapeamento não são relevantes;
  • Por se tratar de uma tabela de mapeamento, ela existirá somente durante o carregamento (load);
  • Nenhuma associação (ligação) será feita nesta tabela;
  • Nenhum erro é gerado se você usar um nome de tabela de mapeamento que não existe

 
 
 

A função

A função ApplyMap possui três parâmetros, sendo:

  • Nome da tabela de mapeamento (deve ser usado entre apóstrofes) – Obrigatório
  • Nome do campo que sofrerá o De-para – Obrigatório
  • Retorno caso não seja encontrado nenhuma valor na tabela de mapeamento – Opcional – Caso não seja preenchido, será retornado o próprio valor do campo que não foi encontrado.

 
 
 

Exemplo simples de utilização

//Criando a tabela de mapeamento

MapaEstado:

Mapping LOAD

UF,

DESC_UF

From Estado.qvd (qvd);

 

//Utilizando a função

ApplyMap(‘MapaEstado’, UF, ‘Não Encontrei’) as DESCRICAO_ESTADO

 
 
 

Orientações

É muito importante utilizarmos o terceiro parâmetro da função com uma string que identifique que nenhum valor foi encontrado, pois dessa forma é possível identificar casos em que a regra utilizada não obteve valor.

Sempre utilize o terceiro parâmetro da função, para retornar algum valor nos casos em que não foi encontrado nenhum mapeamento.

 
 
 

Benefícios

O principal benefício da função é o desempenho na realização do De/Para. É sempre recomendado a utilização do ApplyMap ao invés de JOIN quando se trata da ligação entre duas tabelas grandes. Não acredita? Existem diversos cenários testados que comprovam, procure na comunidade :D!

Outro benefício é que, como dito anteriormente, o ApplyMap funciona apenas em casos de 1:1 (um para um), ou seja, um determinado registro possui apenas um valor a ser mapeado. Caso a função seja utilizada em casos N:1, então será retornado o primeiro registro (De N) do mapeamento para aquele caso e não será gerado nenhum produto cartesiano dos dados.

No exemplo abaixo, o vendedor Yuri possui dois apelidos, ‘Nicolett’ e ‘Yure’. Se fosse realizado um JOIN para interligar essas tabelas, os valores de vendas do vendedor Yuri seria duplicado devido as duas possibilidades de apelido, porém com ApplyMap, somente o primeiro valor encontrado no mapeamento seria retornado (‘Nicolett’) e os valores de vendas permaneceriam inalterados.

 
 

MapaApelido:
Mapping LOAD * INLINE [
NOME, APELIDO
Yuri, Nicolett
Yuri, Yure
Paula, Paulinha
];

 
Fato:
LOAD
ID,
NOME_VEND,
VALOR,
ApplyMap(‘MapaApelido’, NOME_VEND, ‘Achei não!’) as APELIDO
INLINE [
ID, NOME_VEND, VALOR
1, Yuri, 2
2, Yuri, 4
3, Paula, 5
];

 
 

Por último, e não menos importante, é possível se utilizar desse mapeamento para outra tratativa sem a necessidade de um pré-load ou resident, pois ao fazer o mapeamento o novo valor fica disponível para utilização naquele momento.

No exemplo abaixo é calculada o valor de comissão do vendedor em apenas 1 passo:

 

MapaComissao:

Mapping LOAD

VENDEDOR,

PERC_COMISSAO

FROM Comissao.qvd (qvd);

 

Fato:

LOAD

QTD_VENDA * ApplyMap(‘MapaComissao’, VEND, 0) as VALOR_COMISSAO

RESIDENT ….

 
 
 

Casos extremos

Mas Yuri, e se precisar recuperar 4 campos de outra tabela? Valeria a pena criar 4 mapeamentos ou fazer um único join?

Para identificar qual a melhor opção nessa caso eu precisaria de mais um detalhe: O volume de registros das duas tabelas é grande? Passa de 1 milhão de linhas? Vai variar muito daqui N tempo? Se o volume de dados é grande, então não tenho receio algum de te recomentar a utilização de 4 tabelas de mapeamentos e 4 applymaps, caso contrário utilize JOIN.

 
 
 

E mais alguns detalhes

Com o ApplyMap

O terceiro parâmetro da função ApplyMap é muito poderoso, pois você pode utilizar funções ou combinações de campos, por exemplo:

 

1) Retorne um conjunto de campos

ApplyMap(‘Mapeamento’, CAMPO, CAMPO2& ‘-‘ &CAMPO3)

 

2) Caso um mapeamento não funcione, tente outro.

ApplyMap(‘Mapeamento’, CAMPO, ApplyMap(‘MapeamentoDois’, CAMPO2))

/* Sinceramente esse caso é muito interessante, já presenciaram modelagens que a ligação entre duas tabelas pode ser realizada através de duas chaves diferentes? Dependendo da situação através de uma chave ou através de outra? Esse caso pode salvar sua vida rsrs */

 

3) Funções – Verifico condição

ApplyMap(‘Mapeamento’, CAMPO, if( CAMPO2 > CAMPO3, ‘É Maior’, ‘É Menor’))

 
 
 

Conclusão

É sempre bom se utilizarmos desse manual das melhores práticas e o ApplyMap é uma das principais funções para conseguirmos obter o melhor desempenho (de carga) dentro do script das nossas aplicações. Sempre analise seu atual ambiente e em caso de dúvidas faça o teste entre JOIN e ApplyMap.

 

 

 

Até a próxima semana!

 

Melhores Práticas – QVD Optimized

Pessoal, estarei postando diversos passos de melhores práticas em QlikView e gostaria que todos participassem. Acho que vai ficar bem legal!

Vamos lá!

Cargas QVD otimizadas são até 100 vezes mais rápidas do que as não otimizadas. Isso faz muita diferença no tempo de recarga e ainda mais diferença para o desempenho do seu servidor.

A razão para a grande diferença está relacionada ao algoritmo de compressão que o QlikView usa quando armazenamos dados para análise em memória. Arquivos QVD são armazenados em um formato que espelha a compressão utilizada na memória (que é por isso que os arquivos QVD são tão pequenas no disco) e durante uma carga otimizada os dados são enviados diretamente do disco para a memória no mesmo formato comprimido. Quando uma carga não-otimizada é realizada isso não acontece.

Então porque não fazer todas as cargas do QVD otimizado? O simples fato é que algumas operações requerem que os dados sejam descompactados, modificados e em seguida re-embalados. Apenas uma alteração nos dados fará com que uma carga não seja otimizada.

Alguns exemplos que farão com que a carga não seja otimizada:

– Adição de novos campos para a tabela

– Derivando novos valores a partir de um campo na QVD

– Recuperando um campo duas vezes

– Mais condições WHERE

– JOIN em uma tabela de memória

– Carregando dados em uma tabela de mapeamento (mapping load)

Alguns exemplos que farão com que a carga seja otimizada:

– Renomear campos

– LOAD DISTINCT

– Omitir Campos (Omit)

– Where Exists Simples

Quando criamos QVDs incrementais com quebra por mês, ou seja, um qvd por mês (Faturamento_201401.qvd, Faturamento_201402.qvd), na maioria das vezes, quando o cliente deseja restringir a quantidade de meses na aplicação, criamos uma variável e restringimos através de um WHERE MESANO >= $(v_MesAno_Limite), mas a dica aqui é utilizar o EXISTS Simples, ou seja, com um campo só. Vamos para um exemplo:

Quero exibir somente os dados de 2013 e 2014, desta forma realizamos a seguinte lógica:

1) Criar uma tabela (INLINE) com o mesmo nome da coluna da tabela que sofrerá redução dos anos e colocar os valores 2013 e 2014.

OBS: Isso vale para MêsAno, Datas, Produtos ou combinações de colunas.

Restrição:

LOAD * INLINE [

Faturamento.ANO

2014

2013

];

2) Quando realizar a leitura da tabela em que deseja fazer a restrição dos valores, basta realizar a leitura normalmente e adicionar um WHERE Exists para retornar somente os dados de 2014 e 2013.

Faturamento:

LOAD

    Faturamento.ANO,

    Faturamento.MES,

    Faturamento.DATA,

    Faturamento.EMPRESA,

    Faturamento.VALOR

FROM Faturamento_*.qvd (qvd)

WHERE

EXISTS(Faturamento.ANO);

DROP TABLE Restrição;

Repare que a leitura dos qvds manterá o QVD Optimized!

Fontes:

Manual QlikView

Optimized QVD Loads in Qlikview

Qlikview Notes: QVD Questions and Answers