Skip to main content
Announcements
Global Transformation Awards! Applications are now open. Submit Entry
cancel
Showing results for 
Search instead for 
Did you mean: 
Clever_Anjos
Employee
Employee

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:1300:00:2600: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

Labels (1)
7 Replies
mario_sergio_ti
Partner - Specialist
Partner - Specialist

Ótimo post para a galera,

Abraço.

Consultor certificado | Quem compartilha, aprende!
https://www.linkedin.com/in/mariosergioti
Anonymous
Not applicable

Muito bom! conteúdo direto e bastante agregador.

Em aplicações parrudas e com atualizações em intervalos pequenos, essas dicas fazem toda diferença.

Abraços

pedromsouza
Creator II
Creator II

O campo com Hash não irá ocupar muito mais espaço na memória do que um número inteiro? O propósito não era reduzir o peso na memória?

Qliking since '09
Clever_Anjos
Employee
Employee
Author

Se você usar o AutoNumberHash*() ele vai retornar sempre um inteiro, a diferença é que ele faz um hash dos valores antes

Clever_Anjos
Employee
Employee
Author

AutonumberHash256() <=> AutoNumber(Hash256())

pedromsouza
Creator II
Creator II

Sim, entendi a diferença. Obrigado! Vou testar o AutoNumber(Hash256())

Qliking since '09
Jaime_Borges
Partner - Contributor
Partner - Contributor

Excelente post. Parabéns!