A mudança no Identity a partir do SQL Server 2012!



Fala galera tudo certo? Espero que sim!

Hoje vou falar sobre um comportamento do SQL Server 2012 relacionado à utilização da propriedade Identity que muitos já devem ter presenciado ou lido algo sobre.

Para começar, o que é o Identity?

O Identity como já foi dito a cima, é uma propriedade que você define dentro de uma coluna contendo um tipo numérico com o intuito de gerar valores únicos¹ que tenham um incremento automático, por exemplo, uma coluna do tipo INT com um Identity definido em “1,1”, irá crescer sempre de um em um conforme forem sendo feitas as inserções das linhas na tabela. O criador da tabela define o valor inicial e o valor do incremento, ambos são chamados de “seeds”, quando estes não são definidos o SQL Server assume o padrão “1,1”.
¹ Não é garantido que os valores sejam sempre únicos e que nunca ocorram intervalos entre eles, em certas situações estes podem duplicar.

O antes e depois...

Em versões anteriores do SQL Server, sempre que um novo valor do Identity era gerado, este era logado separadamente. No SQL Server 2012 os valores do identity são gerados em batches e apenas o valor máximo é logado, ou seja, com o mínimo de operações sendo logadas a performance do SQL Server em operações evolvendo identity tende a ser melhor.

+10,+100,+10.00,+10.000...

Esta mudança feita no SQL Server 2012 acabou provocando um comportamento peculiar nas colunas Identity. Imagine que uma instância do SQL Server falha sem que o CHECKPOINT seja executado. Durante o restart do serviço, o SQL Server precisa garantir que não irá reutilizar um valor já atribuído a um campo Identity. Para isto, os campos terão seus valores máximos ajustados de um determinado valor, de acordo com o tipo do campo:

Colunas TINYINT = + 10
Colunas SMALLINT = + 100
Colunas INT = + 1.000
Colunas BIGINT = + 10.000

TRACE FLAG -t272

O trace flag -t272, não documentado, faz com que o SQL Server volte a operar da maneira antiga com relação ao Identity. Ou seja, para cada novo valor gerado será persistido no log.

Simulando o comportamento...

CREATE DATABASE TesteDB
GO

USE TesteDB
GO

CREATE TABLE SimulaID
(
ID INT IDENTITY,
NOME VARCHAR(20)
)
GO

INSERT INTO SimulaID VALUES ('SQL')
INSERT INTO SimulaID VALUES ('MAGU')

--VEJA O RESULTADO…

SELECT ID,NOME FROM SimulaID


--PARE O SQL SERVER COM O COMANDO SHUTDOWN WITH NOWAIT...

SHUTDOWN WITH NOWAIT

Server shut down by NOWAIT request from login --\Andre Cesar.
SQL Server is terminating this process.

--SUBA O SERVIÇO DO SQL NOVAMENTE...

C:\Windows\system32>net start "MSSQL$MSSQL2014" << Troque pelo nome da sua instância...
The SQL Server (MSSQL2014) service is starting.
The SQL Server (MSSQL2014) service was started successfully.

INSIRA NOVAMENTE DOIS VALORES NA TABELA...

USE TesteDB
GO

INSERT INTO SimulaID VALUES ('SQL')
INSERT INTO SimulaID VALUES ('MAGU')

--VEJA NOVAMENTE O RESULTADO, REPARE NO SALTO DO IDENTITY...


Agora, habilite o trace flag -t272 nos parâmetros de inicialização do SQL Server e reinicie o serviço...

 
 
Com o serviço no ar novamente, faça os procedimentos abaixo...

--LIMPE A TABELA...

TRUNCATE TABLE SimulaID

--INSIRA DOIS VALORES NA TABELA..

USE TesteDB
GO

INSERT INTO SimulaID VALUES ('SQL')
INSERT INTO SimulaID VALUES ('MAGU')

--PARE O SQL SERVER NOVAMENTE COM O COMANDO SHUTDOWN WITH NOWAIT...

SHUTDOWN WITH NOWAIT

--SUBA O SERVIÇO DO SQL NOVAMENTE...

C:\Windows\system32>net start "MSSQL$MSSQL2014" << Troque pelo nome da sua instância...
The SQL Server (MSSQL2014) service is starting.
The SQL Server (MSSQL2014) service was started successfully.


--INSIRA NOVAMENTE DOIS VALORES NA TABELA..

USE TesteDB
GO

INSERT INTO SimulaID VALUES ('SQL')
INSERT INTO SimulaID VALUES ('MAGU')

--VEJA O RESULTADO AGORA QUE O TRACE FLAG ESTÁ LIGADO…

SELECT ID,NOME FROM SimulaID


Fontes:

Nenhum comentário:

Postar um comentário