Em uma das minhas tabelas Fee
da coluna "ReceiptNo" no SQL Server 2012, o incremento de identidade do banco de dados começou subitamente a saltar para 100s em vez de 1, dependendo das duas coisas a seguir.
se for 1205446, saltar para 1206306, se for 1206321, saltar para 1207306 e se for 1207314, saltar para 1208306. O que quero fazer você notar é que os últimos três dígitos permanecem constantes, ou seja, 306 sempre que o salto ocorre como mostrado na figura a seguir.
esse problema ocorre quando eu reinicio o computador
order by ReceiptNo
à sua consulta, esses registros realmente não estão lá? Tem certeza de que quando os registros estão sendo inseridos, não há erros? Se um registro tentar ser inserido e falhar, a identidade será incrementada, o mesmo se os registros forem excluídos. Se os registros forem excluídos,ReceiptNo
não será redefinido. Você pode postar a tabela de criação para aFee
tabela?1206306
,1207306
,1207806
) significa a explicação no tópico do item Ligação quase certamente se aplica.Respostas:
Você está enfrentando esse comportamento devido a uma melhoria de desempenho desde o SQL Server 2012.
Agora, por padrão, usa um tamanho de cache de 1.000 ao alocar
IDENTITY
valores para umaint
coluna e reiniciar o serviço pode "perder" valores não utilizados (o tamanho do cache é de 10.000 parabigint
/numeric
).Isso é mencionado na documentação
A partir dos dados que você mostrou, parece que isso aconteceu após a entrada de dados de 22 de dezembro e, quando reiniciou o SQL Server, reservou os valores
1206306 - 1207305
. Após a entrada de dados de 24 a 25 de dezembro, foi feita outra reinicialização e o SQL Server reservou o próximo intervalo1207306 - 1208305
visível nas entradas do dia 28.A menos que você esteja reiniciando o serviço com frequência incomum, é improvável que quaisquer valores "perdidos" afetem significativamente o intervalo de valores permitido pelo tipo de dados, portanto, a melhor política é não se preocupar com isso.
Se, por algum motivo, isso for um problema real, algumas soluções possíveis são:
SEQUENCE
coluna em vez de uma identidade e definir um tamanho de cache menor, por exemplo, e usarNEXT VALUE FOR
em uma coluna padrão.IDENTITY
alocação registrada como nas versões até 2008 R2. Isso se aplica globalmente a todos os bancos de dados.ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
para desativar o cache de identidade de um banco de dados específico.Você deve estar ciente de que nenhuma dessas soluções alternativas garante nenhuma lacuna. Isso nunca foi garantido
IDENTITY
, pois somente seria possível serializando inserções na tabela. Se você precisar de uma coluna gapless você vai precisar usar uma solução diferente do que qualquer umIDENTITY
ouSEQUENCE
fonte
SEQUENCE
vez de umIDENTITY
e definir a sequência para ter um tamanho de cache igual a0
.CREATE TABLE
vejo que você está usandonumeric(7)
e começou a numeração, o1200001
que significa que você acabaria após8,799
dias (24 anos) se usasse 1.000 por dia.big int
coluna geralmente "aumenta" em 10.000 por reinicialização.Esse problema ocorre após reiniciar o SQL Server.
A solução é:
Execute o SQL Server Configuration Manager .
Selecione Serviços do SQL Server .
Clique com o botão direito do mouse em SQL Server e selecione Propriedades .
Na janela de abertura, em Parâmetros de inicialização , digite
-T272
e clique em Adicionar , pressione o botão Aplicar e reinicie.fonte
De
SQL Server 2017+
você poderia usar ALTER DATABASE SCOPED CONFIGURATION :fonte
Eu sei que minha resposta pode estar atrasada para a festa. Mas resolvi de outra maneira adicionando um procedimento armazenado de inicialização no SQL Server 2012.
Crie um procedimento armazenado a seguir no banco de dados mestre.
Em seguida, adicione-o à Inicialização usando a seguinte sintaxe.
Essa é uma boa ideia se você tiver poucas tabelas. mas se você precisar fazer isso para muitas tabelas, esse método ainda funcionará, mas não é uma boa ideia.
fonte
Esse ainda é um problema muito comum entre muitos desenvolvedores e aplicativos, independentemente do tamanho.
Infelizmente, as sugestões acima não corrigem todos os cenários, ou seja, hospedagem compartilhada, você não pode confiar no seu host para definir o parâmetro de inicialização -t272.
Além disso, se você possui tabelas existentes que usam essas colunas de identidade para chaves primárias, é um enorme esforço para eliminar essas colunas e recriar novas para usar a solução alternativa da sequência BS. A solução alternativa de Sequência só é boa se você estiver criando as tabelas novas do zero no SQL 2012+
A linha inferior é, se você estiver no Sql Server 2008R2, FIQUE LIGADO. Sério, fique nele. Até a Microsoft admitir que eles introduziram um bug ENORME, que ainda existe no Sql Server 2016, não devemos atualizar até que eles sejam os proprietários e o CORRETAMENTE.
A Microsoft introduziu imediatamente uma mudança de quebra, ou seja, quebrou uma API funcional que não funciona mais como projetada, devido ao fato de que seu sistema esquece sua identidade atual em uma reinicialização. Cache ou sem cache, isso é inaceitável, e o desenvolvedor da Microsoft, com o nome de Bryan, precisa possuí-lo, em vez de dizer ao mundo que é "por design" e um "recurso". Certamente, o armazenamento em cache é um recurso, mas perder a noção do que deve ser a próxima identidade NÃO É UM RECURSO. É um erro fricken !!!
Compartilharei a solução alternativa que usei, porque os Meus DBs estão em servidores de Hospedagem Compartilhada e também não estou descartando e recriando minhas colunas de Chave Primária, que seria uma PITA enorme.
Em vez disso, esse é meu truque vergonhoso (mas não tão vergonhoso quanto esse bug do POS que a microsoft introduziu).
Hack / Correção:
Antes dos comandos de inserção, basta reenviar sua identidade antes de cada inserção. Essa correção é recomendada apenas se você não tiver controle de administrador sobre sua instância do Sql Server; caso contrário, sugiro que continue com a reinicialização do servidor.
Apenas essas três linhas imediatamente antes da inserção e você deve estar pronto. Realmente não afetará muito o desempenho, ou seja, será imperceptível.
Boa sorte.
fonte
Existem muitas razões possíveis para saltar valores de identidade. Eles variam de inserções revertidas ao gerenciamento de identidades para replicação. O que está causando isso no seu caso, não posso dizer sem passar algum tempo no seu sistema.
No entanto, você deve saber que, em nenhum caso, você pode assumir que uma coluna de identidade é contiguosa. Existem muitas coisas que podem causar lacunas.
Você pode encontrar um pouco mais de informações sobre isso aqui: http://sqlity.net/en/792/the-gap-in-the-identity-value-sequence/
fonte