Recentemente eu estava lendo esta postagem no blog: Link
que contém esta seção:
Escolhendo um índice agrupado
Existem algumas estratégias para escolher seus índices clusterizados; um dos mais fáceis e melhores é adicionar outra coluna de tipo de dados datetime e usar essa coluna para seu índice clusterizado. Aqui está o que você precisa fazer:
Adicione a coluna como tipo de dados datetime
Eu costumo chamá-lo de data
Defina o valor padrão como GetDate().
Torne-o não nulo.
Crie seu índice clusterizado nele antes de inserir dados em você.
Minha pergunta é se isso criaria dois valores idênticos para a data? Essa resposta muda se o paralelismo estiver em uso? (Assume valor nunca especificado, sempre vem de GetDate())
Acredito que estou correto ao presumir que não importaria devido à adição do exclusivo de bastidores, certo? Mas estou interessado de qualquer maneira.
Estou perguntando de uma perspectiva do SQL2008R2, mas estaria interessado se a resposta for diferente para qualquer versão do SQL Server de 7.0 para cima.
GETDATE()
não é garantido que seja único, não. Especialmente se for um datetime, onde os milissegundos são arredondados para cima ou para baixo e, claro, quando nem todos os dados vêm do mesmo usuário, é quase certo que haverá colisões.É claro que um índice clusterizado não precisa ser exclusivo, pois o SQL Server o tornará se não for (mas apenas quando necessário). Se você mesmo precisar identificar uma linha específica (em vez de apenas o unificador para uso interno do SQL Server) e não houver outras colunas de chave candidatas (isso é possível com coisas como tabelas de log de eventos), você pode adicionar um não clusterizado chave primária que é, digamos, uma coluna IDENTITY. Ou se você realmente deseja escalar na web - e se preocupa mais com o desempenho de inserção do que com o armazenamento ou qualquer uso subsequente dos dados - você pode usar uma coluna de identificador único preenchida com NEWID().
Exemplo
Vamos dar uma olhada em um exemplo e ver as diferenças.
Inserir velocidade
Preenchi todas as três tabelas com cerca de 500.000 linhas, usando o seguinte script:
Resultados:
Velocidade de digitalização
Resultados:
Espaço usado
Olhando para resultados simples de
sp_spaceused
:Resultados:
O uniquifier ocupa menos espaço que a coluna IDENTITY (e obviamente ambos ocupam menos que o GUID), pois é necessário apenas para colisões (e provavelmente outras otimizações que desconheço, como compactação).
Também podemos examinar as páginas de índice para o índice clusterizado na coluna datetime (index id = 1) e a chave primária não clusterizada (index id = 2):
Conteúdo da página/linha
E, finalmente, podemos dar uma olhada em uma página específica para ver o que está armazenado em uma linha. Eu simplesmente peguei a primeira linha de cada um dos resultados DBCC IND do índice clusterizado acima (seus valores de id de página quase certamente serão diferentes):
Uniquifier - preste atenção especial ao comprimento/tamanho do registro:
IDENTITY parece ter 4 bytes extras no índice clusterizado:
O GUID tem 16 bytes extras no índice clusterizado:
Conclusão
Parece-me que, de acordo com todas as contas, é melhor deixar o unificador fazer suas próprias coisas (supondo que você não espere ser capaz de diferenciar entre duas linhas com exatamente o mesmo valor de data/hora). A única vez que você pode ter problemas com isso, se qualquer valor único for duplicado 2.147.483.648 vezes, ponto em que você ultrapassará o intervalo do unificador de número inteiro.