Numérico vs Inteiro para uma coluna - tamanho e desempenho

11

Eu tenho um aplicativo que usa uma tabela do PostgreSQL. A tabela é muito grande (bilhões de linhas) e possui uma coluna que é um número inteiro.

A integerpode ser de até 6 dígitos, ou seja, não há 0-999,999 negativos.

Eu pensei em mudar para ser numeric(6,0).

Isso seria uma boa ideia? Iria numeric(6,0)demorar menos bytes? E o desempenho (esta tabela está sendo consultada muito)?

Ofiris
fonte

Respostas:

11

Isso seria uma boa ideia?

Não.

iria numeric(6,0)demorar menos bytes?

Não.

test=> SELECT pg_column_size(INT4 '999999'), pg_column_size(NUMERIC(6,0) '999999');
 pg_column_size | pg_column_size 
----------------+----------------
              4 |             10
(1 row)

e quanto ao desempenho (esta tabela está sendo consultada muito)?

Mais devagar. Ele é armazenado como decimal codificado em binário porque é um valor de precisão arbitrário.

Craig Ringer
fonte
Tudo concordado, como uma nota lateral numérica tem uma vantagem, uma vez que impõe automaticamente o domínio 0-999999. Isso pode, contudo, ser resolvido com uma restrição em separado no caso int
Lennart
11
Ocorreu um problema ao alterar uma numericcoluna para int?
Racer SQL
@RacerSQL Sim, se você tiver valores que excederão o tamanho int.
DylanYoung 25/03
5

A resposta definitiva é não a todas as suas perguntas. Inteiro é sempre o caminho a percorrer para qualquer coisa que você possa usá-lo. (Dinheiro, por exemplo)

Pense sobre isso por um minuto. Quando o mecanismo de banco de dados encontra um número inteiro, ele lida com muita eficiência, porque não há muita interpretação para ele. É um número inteiro. O tipo numérico se comporta mais como uma string. O mecanismo primeiro precisa descobrir quais partes estão antes e depois do ponto decimal e massageá-las adequadamente para executar operações numéricas.

Usar um número inteiro sempre será mais eficiente que um numérico, embora tipos numéricos sejam frequentemente mais convenientes para humanos.

stubsthewizard
fonte
Eu discordo quando se trata de dinheiro. Usar um número inteiro escalado, como armazenar decicentes (1000 por dólar), é bom, mas estranho. Torna-se rapidamente mais prático de usar NUMERIC. Um número inteiro escalado é muito melhor do que usar um valor de ponto flutuante por dinheiro.
Craig Ringer
2
@ CraigRinger Eu não acho que você realmente discorda de mim! Concordo que usar um decimal por dinheiro é sempre menos complicado para o desenvolvedor, mas a questão é a eficiência da consulta, certo? Manipular números inteiros é sempre mais rápido. Além disso, ao escrever aplicativos bancários, você pode se deparar com alguns problemas estranhos de arredondamento com os quais a maioria das pessoas não se importaria, mas são muito importantes para os bancos. Então, eu também concordo com você em não usar ponto flutuante por dinheiro também!
stubsthewizard
11
Bom ponto de arredondamento. Eu gostaria que o PostgreSQL tivesse suporte a políticas de arredondamento. Porém, não deseje o suficiente para implementá-lo;)
Craig Ringer