Eu tenho uma coluna do tipo "comentário" que raramente é usada - cerca de 6% não nula em uma população de 3 milhões de registros. O comprimento médio (quando usado) é de 6 caracteres e o máximo até agora é de cerca de 3 KB. Um máximo de 4000 caracteres é razoável para este campo. Eu tenho duas opções:
comments varchar(max) NULL -- this is the current column definition
comments varchar(4000) SPARSE NULL
Meu entendimento atual é que, em ambos os casos, um NULL
valor não exigiria armazenamento - apenas o NULL
conjunto de bits da coluna e um comprimento 0
nos metadados da linha.
Mas para os casos não nulos , um tem clara vantagem sobre o outro?
O ponteiro extra de 4 bytes para colunas esparsas com valores sugere que eles são sempre armazenados fora da linha ou em campos text
muito grandes . varchar(max)
É esse o caso?
Nesse caso, eu me inclinaria a usar varchar(max)
, já que ele só armazena valores fora da linha se o comprimento total da linha exceder 8 KB, e a maioria dos meus valores é curta e é improvável que coloque uma linha acima do limite.
Não vi essa situação específica abordada no BOL, então espero que alguém aqui saiba o suficiente sobre as entranhas do MSSQL para fornecer algumas dicas.
(Se for importante, atualmente estou usando 2008R2, mas espero atualizar em breve para 2014.)
Não há vantagem para os casos não NULL ao usar
SPARSE
, e de fato, existem duas desvantagens declaradas:Como você já percebeu, a
SPARSE
opção só faz sentido para tipos de dados de comprimento fixo; Não consigo pensar em um único motivo para usá-lo em tipos de comprimento variável.Não tenho certeza de que os 4 bytes extras impliquem algo sobre o armazenamento fora da linha, e os
MAX
tipos não estão totalmente fora da linha quando excedem 8.000 bytes, pois há o ponteiro de 16 bytes na linha para esse off-line. localização da linha.Fique com
VARCHAR(4000)
, noSPARSE
, e eu consideraria fazê-loNOT NULL DEFAULT('')
(uma string vazia ainda tem 0 bytes, mas agora você não precisa mexer com o indicador NULL e um comentário pode realmente ser "desconhecido" em vez de "sem comentário "?).Eu apoio Srutzky. Concordou.
Agora, deixe-me acrescentar um pouco da perspectiva operacional que tem muito a ver com a sua decisão. Como você está atualmente em varchar (max), não há problema para você, mas fugir disso tem certas vantagens em desempenho e recursos operacionais.
Apenas para dar um exemplo, há um recurso útil chamado Reconstrução de Índice Online, que é um recurso exclusivo da edição corporativa.
Permita-me desviar um pouco; Após um longo período de uso, os índices ficam fragmentados e precisam ser reconstruídos. No entanto, as compilações usuais causariam um bloqueio significativo nas tabelas subjacentes e, enquanto o índice está sendo reconstruído, o índice não é utilizável, o que torna as consultas inoperantes em bancos de dados muito grandes. Não é apenas "hmm..é meio lento", é "2 segundos de consulta leva 25 minutos!" tipo de emergência. Portanto, em um sistema 24 horas por dia, 7 dias por semana, não é uma opção. É aí que a reconstrução do índice online entra em jogo; se você pagou cerca de US$ 25.000 pela licença principal do privilégio de usar a Enterprise Edition, pode recriar magicamente o índice em um sistema 24 horas por dia, 7 dias por semana, sem afetar os usuários.
Exceto, se algum desenvolvedor lançar varchar (max), não funcionará. Felizmente, no entanto, em varchar(4000). Se os dados contivessem mais de 8.000 caracteres, você ficaria preso em varchar(max) e não conseguiria realizar a reconstrução online, o que seria um problema operacional que os superiores certamente notariam.
..e esse é apenas um exemplo. Portanto, minha recomendação é conversar com o DBA de produção em sua organização e perguntar a eles o que eles gostam e o que não gostam. Como você está executando varchar(max), entendo que não é um problema, mas você pode prepará-lo para o futuro removendo-o. Embora, você estaria perfeitamente bem com o uso de varchar(max) se a tabela for para armazenamento acessado com pouca frequência, sem necessidade de reconstrução de índice online. Esse é o tipo de chamada que apenas seu DBA de produção pode fazer.
Se você estiver em uma loja menor sem DBA dedicado, forneça mais detalhes sobre o uso da tabela e os requisitos operacionais (é 24 horas por dia, 7 dias por semana, com exigência de cinco noves? É clusterizado? Quanto tempo dura sua janela de serviço? Edição atual e planos futuros para mudanças de edição?) e a comunidade pode lhe dar melhores recomendações. Posso estar pedindo muita informação, mas esse é o tipo de detalhe com o qual os DBAs experientes contam para tomar a decisão certa.