Autonumber x AutonumberHash128 x AutonumberHash256 em chaves compostas

Olá pessoal,

É uma recomendação que as suas chaves (campos que ligam as tabelas) sejam sempre numéricas para otimizar o uso de memória.

Várias vezes recorremos ao uso da função Autonumber() e suas “primas” AutonumberHash128() e Autonumber256() para converter uma chave string para uma chave numérica.

Se você quiser ler o que diz a documentação dessas funções

Autonumber

AutonumberHash128

AutonumberHash256

 

Você pode notar que todas as três retornam um inteiro sequencial, baseado na ordem que seus parâmetros. A diferença entre elas é que as AutonumberHash128() e Autonumber256() calculam antes um “hash” (Wikipedia) .

 

Existe um “trade-off” nessa estratégia, qualquer uma delas gasta um tempo para executar o pseudo-algoritmo abaixo

  • Esse parâmetro já foi carregado?
  • Se sim, retorna o sequencial calculado anteriormente
  • Se não, incrementa o sequencial e armazena

 

É usual encontrar situações em que a presença de um “autonumber” (qualquer um dos três) adicione até 20% no tempo de carga dos dados. Usualmente aceita-se esse tempo em troca da economia de memória da aplicação final.

 

Mas ai vem uma pergunta:

“Sei que essas funções geram uma lentidão, mas qual devo usar?”


Resolvi fazer alguns testes para comparar a velocidade de cada um deles.

Obs.:Eu foquei na geração de chaves compostas (mais de um campo) pelo fato que usualmente é o que precisamos quando montamos nossas tabelas, link-tables, etc

 

Para chaves compostas, a função Autonumber() tem uma pequena diferença em relação as outras duas.

A sintaxe dela é:

autonumber(expression[ , AutoID]) — Esse AutoID é qual tabela de incrementos ela vai usar, podendo reiniciar de acordo com ela

Se eu precisar de uma chave composta, eu preciso concatenar com & os parâmetros

RegionSales: 
LOAD *, 
AutoNumber(Region&Year&Month) as RYMkey; // <-- Preciso concatenar com &
LOAD * INLINE [ 
Region, Year, Month, Sales 
North, 2014, May, 245 
North, 2014, May, 347 
North, 2014, June, 127 
South, 2014, June, 645 
South, 2013, May, 367 
South, 2013, May, 221];



As outras duas é:

autonumberhash128(expression {, expression}) — Posso passar uma lista de parâmetros, sem precisar concatenar

RegionSales:
LOAD *,
AutoNumberHash128(Region, Year, Month) as RYMkey; // <-- Não preciso concatenar com &
LOAD * INLINE [
Region, Year, Month, Sales
North, 2014, May, 245
North, 2014, May, 347
North, 2014, June, 127
South, 2014, June, 645
South, 2013, May, 367
South, 2013, May, 221];

 

Esse “esforço” de concatenar quando usamos a autonumber() aparentemente impacta o desempenho.

Abaixo o script que usei, onde gero uma massa com 10 milhões de registros, gerando o sequencial e salvando o cronômetro

Let quant = 10000000;

Let v1=now();
t1:
LOAD
ID,
AutoNumber(ID&Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);

Let v2=now();
t2:
LOAD
ID,
AutoNumberHash128(ID,Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);

Let v3=now();
t3:
LOAD
ID,
AutoNumberHash256(ID,Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);
Let v4=now();

drop Table t1,t2,t3;

 

Depois fiz uma pequena aplicação comparando os dados

v2-v1 v3-v2 v4-v3
00:01:13 00:00:26 00:00:24

 

Podemos notar que as AutonumberHas128() e AutonumberHash256() praticamente se equivalem, mas são bem mais rápidas que a Autonumber(). Muito provavelmente isso deve-se à necessidade de concatenar as strings utilizando-se o &.

 

Eu acredito que esses resultados irão variar conforme a frequência de repetição, tamanho dos campos entre outras fatores.

Faça seus testes e comente aqui a que resultado

 

images?q=tbn:ANd9GcQtGSNKsAMBOcg5_XjpRjZOMe6nJNe1NBmM9EorWQ3s3eMNkIU_Og

Continue reading

Autonumber x AutonumberHash128 x AutonumberHash256 em chaves compostas

Olá pessoal,

É uma recomendação que as suas chaves (campos que ligam as tabelas) sejam sempre numéricas para otimizar o uso de memória.

Várias vezes recorremos ao uso da função Autonumber() e suas “primas” AutonumberHash128() e Autonumber256() para converter uma chave string para uma chave numérica.

Se você quiser ler o que diz a documentação dessas funções

Autonumber

AutonumberHash128

AutonumberHash256

 

Você pode notar que todas as três retornam um inteiro sequencial, baseado na ordem que seus parâmetros. A diferença entre elas é que as AutonumberHash128() e Autonumber256() calculam antes um “hash” (Wikipedia) .

 

Existe um “trade-off” nessa estratégia, qualquer uma delas gasta um tempo para executar o pseudo-algoritmo abaixo

  • Esse parâmetro já foi carregado?
  • Se sim, retorna o sequencial calculado anteriormente
  • Se não, incrementa o sequencial e armazena

 

É usual encontrar situações em que a presença de um “autonumber” (qualquer um dos três) adicione até 20% no tempo de carga dos dados. Usualmente aceita-se esse tempo em troca da economia de memória da aplicação final.

 

Mas ai vem uma pergunta:

“Sei que essas funções geram uma lentidão, mas qual devo usar?”


Resolvi fazer alguns testes para comparar a velocidade de cada um deles.

Obs.:Eu foquei na geração de chaves compostas (mais de um campo) pelo fato que usualmente é o que precisamos quando montamos nossas tabelas, link-tables, etc

 

Para chaves compostas, a função Autonumber() tem uma pequena diferença em relação as outras duas.

A sintaxe dela é:

autonumber(expression[ , AutoID]) — Esse AutoID é qual tabela de incrementos ela vai usar, podendo reiniciar de acordo com ela

Se eu precisar de uma chave composta, eu preciso concatenar com & os parâmetros

RegionSales: 
LOAD *, 
AutoNumber(Region&Year&Month) as RYMkey; // <-- Preciso concatenar com &
LOAD * INLINE [ 
Region, Year, Month, Sales 
North, 2014, May, 245 
North, 2014, May, 347 
North, 2014, June, 127 
South, 2014, June, 645 
South, 2013, May, 367 
South, 2013, May, 221];



As outras duas é:

autonumberhash128(expression {, expression}) — Posso passar uma lista de parâmetros, sem precisar concatenar

RegionSales:
LOAD *,
AutoNumberHash128(Region, Year, Month) as RYMkey; // <-- Não preciso concatenar com &
LOAD * INLINE [
Region, Year, Month, Sales
North, 2014, May, 245
North, 2014, May, 347
North, 2014, June, 127
South, 2014, June, 645
South, 2013, May, 367
South, 2013, May, 221];

 

Esse “esforço” de concatenar quando usamos a autonumber() aparentemente impacta o desempenho.

Abaixo o script que usei, onde gero uma massa com 10 milhões de registros, gerando o sequencial e salvando o cronômetro

Let quant = 10000000;

Let v1=now();
t1:
LOAD
ID,
AutoNumber(ID&Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);

Let v2=now();
t2:
LOAD
ID,
AutoNumberHash128(ID,Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);

Let v3=now();
t3:
LOAD
ID,
AutoNumberHash256(ID,Valor);
load
RecNo() as ID,
Rand() as Valor
autogenerate $(quant);
Let v4=now();

drop Table t1,t2,t3;

 

Depois fiz uma pequena aplicação comparando os dados

v2-v1 v3-v2 v4-v3
00:01:13 00:00:26 00:00:24

 

Podemos notar que as AutonumberHas128() e AutonumberHash256() praticamente se equivalem, mas são bem mais rápidas que a Autonumber(). Muito provavelmente isso deve-se à necessidade de concatenar as strings utilizando-se o &.

 

Eu acredito que esses resultados irão variar conforme a frequência de repetição, tamanho dos campos entre outras fatores.

Faça seus testes e comente aqui a que resultado

 

images?q=tbn:ANd9GcQtGSNKsAMBOcg5_XjpRjZOMe6nJNe1NBmM9EorWQ3s3eMNkIU_Og

Continue reading