[firebase-br] Velocidade em select CHAR X VARCHAR

Sandro Souza escovadordebits em gmail.com
Ter Jun 9 09:04:38 -03 2009


Bom dia/tarde Marcelo.

Grande Marcelo, apoio o que o nosso grande amigo Eduardo Jedliczka postou.

Só complementando o que ele já postou, ainda sugiro que o banco tenha sido
criado no dialeto 3, permitindo assim que você possa usufruir de melhores
recursos do Firebird, como por exemplo, a maior precisão numérica.

Quando você cria campos do tipo FLOAT ou DOUBLE PRECISION, ou então do tipo
NUMERIC ou DECIMAL em dialetos inferiores a 3, o Firebird armazena-os como
números de ponto flutuante, ou seja, são apenas aproximações numéricas.

Nesse cenário, quando você armazena 1, estará armazenando
0.99999999999999999999, o que é aproximadamente 1, mas não EXATAMENTE 1. E
esse problema de precisão começa a ser visível quando você efetua somatórios
e médias, podendo dar resultados diferentes do esperado.

No dialeto 3, o Firebird faz o possível para tentar armazenar os campos de
tipo NUMERIC e/ou DECIMAL internamente como valores inteiros, justamente
para permitir o máximo de precisão numérica.

Nesse mesmo dialeto, a quantidade de dígitos totais do campo determinará o
tipo de inteiro a ser utilizado (SMALLINT, INTEGER ou BIGINT), já que cada
um deles tem seus limites de precisão numérica.

Resumindo, criei a seguinte tabela:

+-------------+------------------------------+
|   Dígitos   |         Tipo interno         |
+-------------+------------------------------+
| De 1 até  4 | SMALLINT (16 bits = 2 bytes) |
| De 5 até  8 | INTEGER  (32 bits = 4 bytes) |
| De 9 até 18 | BIGINT   (64 bits = 8 bytes) |
+-------------+------------------------------+

Com relação às casas decimais, são feitas divisões e multiplicações por
potências de 10 (de acordo com a quantidade de casas decimais) nos momentos
em que esses valores são utilizados nos cálculos.

Agora relacionando todo esse "blá blá blá" com a sua questão:

Se você preferir armazenar esses valores como strings (CHAR(12) ou
VARCHAR(12)), então cada valor, no mínimo, vai consumir 12 bytes/caracteres
de espaço interno.

Se você criou o seu banco de dados no dialeto 3 e preferir armazenar esses
valores como NUMERIC(12,0) ou DECIMAL(12,0), então esses valores serão
armazenados internamente como valores inteiros de 64 bits (BIGINT), ocupando
apenas 8 bytes/caracteres, ou seja, uma economia de 1/3 (33%) de espaço em
relação aos 12 bytes/caracteres.

Isso influencia não apenas no espaço gasto no armazenamento desses valores
como também na velocidade das consultas, visto que são menos bytes a serem
comparados.

De qualquer forma, é apenas uma sugestão.

Espero ter ajudado mais que atrapalhado. :D

2009/6/8 Marcelo Moreira <marcelomoreira.souza em gmail.com>

> Pessoal,
>
> No firebird 2.1 vou precisar fazer um select em uma tabela que vai guardar
> numeros por exemplo: '553184200001'
> Estou na duvida se uso um campo do tipo:
>
> VARCHAR(12) ou
> CHAR(12)
>
> Detalhe que este campo vai vai ser minha PK.
>
> Nesta situação qual seria a melhor escolha?
>
> Obrigado.
>
> Abraços!
>
> --
> Marcelo Moreira
> (31) 8420-2723
> E-mail / MSN: marcelomoreira.souza em hotmail.com
> E-mail: marcelomoreira.souza em gmail.com
> Skype: marcelomoreira.souza
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>



Mais detalhes sobre a lista de discussão lista