As colunas vazias ocupam espaço em uma tabela?

20

Eu tenho uma tabela que contém informações muito básicas. Apenas um título e alguns campos de data. Há um campo chamado comments, que é varchar (4000). Na maioria das vezes, deixamos em branco, mas algumas vezes inserimos uma grande quantidade de dados aqui. Esse design é realmente ruim? Ou isso é apenas um pouco ineficiente?

Eu assumiria que a criação de uma tabela separada para esta coluna seria melhor.

nota: este é o sql server 2008

insira a descrição da imagem aqui

aron
fonte
Obrigado pela sua opinião a todos! Decidi mantê-lo simples e manter a coluna na tabela e não colocá-la em outra tabela. No entanto, usei o recurso SPARSE no SQL 2008 para que o campo não use espaço.
2
Apenas curioso, o que é "na maioria das vezes"? Quantas linhas totalizam e qual porcentagem tem um valor aqui? Basta saber se você está planejando fazer quaisquer comparações espaço / desempenho usando SPARSEe não usando SPARSE...
Aaron Bertrand

Respostas:

9

Para um desempenho mais previsível (e para evitar uma alta variação de linhas por página), eu gostaria de armazenar esses dados em uma tabela relacionada - especialmente se ele for preenchido apenas uma pequena porcentagem do tempo e, especialmente, se for recuperado apenas em algumas das consultas. As linhas em que esse valor está NULLcontribuem para a sobrecarga de espaço, mas isso é mínimo. Mais importante será como uma página pode caber apenas duas linhas e a próxima página pode caber 500 linhas - isso pode realmente afetar as estatísticas e é melhor dividi-las para que sejam armazenadas separadamente e não afetem todas as suas operações. a tabela principal.

Aaron Bertrand
fonte
12

Requer espaço mínimo quando não usado

  • um bit no bitmap NULL
  • dois bytes de comprimento (que será zero quando NULL)

A sobrecarga é mínima e a otimização será prematura.

Até você saber que tem um problema, mantenha-o em uma tabela. Você quebra o KISS introduzindo junções externas e adiciona uma sobrecarga na consulta dos dados.

Consulte /programming/3793022/how-to-come-to-limits-of-8060-bytes-per-row-and-8000-per-varchar-nvarchar-valu/3793265#3793265 para obter mais informações

gbn
fonte
10

Eu acho que uma tabela separada seria melhor para melhorar a densidade da página e reduzir a fragmentação, especialmente se você nem sempre preencher esse campo.

  • Uma página de dados contém cerca de 8000 bytes
  • Você tem algumas linhas com digamos 100 bytes e algumas linhas com mais de 4000 bytes
  • Essas linhas longas estarão em uma página por si mesmas e o restante da página será "desperdiçado" espaço que seu banco de dados ocupa, mas provavelmente nunca conterá dados
  • Se você adicionar dados a esse campo longo para um registro em uma página na maior parte completa, ele provavelmente ultrapassará a página e resultará em um ponteiro para a página com o restante do registro.

Todas essas páginas e ponteiros vazios levam a um desempenho ruim. Normalize esse campo, se puder.

JNK
fonte
4

Esta pergunta é muito parecida: as colunas vazias extras afetam significativamente o tamanho da tabela sql?

Parece que a resposta é sim, ela ocupa espaço, mas existe um algoritmo de compactação para colunas com muitos valores nulos.

Quanto ao design, acho que ter uma tabela externa vinculada a isso seria um design mais limpo. Ter uma coluna com valores nulos frequentes torna mais difícil para os usuários do banco de dados, pois eles podem usar acidentalmente um valor nulo se não tiverem cuidado. Portanto, o código que usa o banco de dados precisa conter a verificação de erros e fica feio a partir daí.

Comunidade
fonte
2
Para ser explícito, o algoritmo de compactação se aplica somente àquelas colunas explicitamente definidas como SPARSE, e não apenas "colunas com muitos valores nulos".
Aaron Bertrand
2

Você ficará bem - já é uma coluna varchar, portanto, ela só usa espaço quando contém dados. Se você tiver muitas colunas de tamanho fixo anuláveis, como int, poderá ter problemas de uso de espaço.

Quanto a colocá-lo em outra mesa, eu não me incomodaria. Você também pode usar varchar (max) e as opções de entrada / saída de linha. Mais uma vez, provavelmente prematuro.

Cade Roux
fonte
11
A otimização prematura geralmente pode ser um problema real, mas isso depende do custo da refatoração posteriormente. Se você sabe hoje que apenas 1% de suas linhas terá dados nesta coluna e espera que a tabela cresça ao longo do tempo, qual é o valor de manter esses dados na tabela atual apenas para sofrer consequências à medida que você escala? Sou a favor de evitar a otimização prematura, mas há um momento em que peso o efeito a longo prazo de fazê-lo.
Aaron Bertrand
@Aaron Bertrand concordou. As pessoas fazem perguntas de desempenho aqui e é fácil supor que eles possam ter um aplicativo com milhões de linhas e que precisam usar todas as armas do kit de ferramentas e manter tudo isso em mente. Por outro lado, às vezes o usuário parece estar no início de uma curva de aprendizado e é difícil pedir que dedique tempo a algo que provavelmente deve ser mais baixo em suas prioridades. Além disso, com varchar (max), você pode pressionar com eficiência um botão para começar a armazenar fora de linha. Eu acho que a resposta real aqui é "Você realmente não nos deu informações suficientes para dar uma resposta definitiva".
Cade Roux