Desde que se escribió el artículo de Itzik Ben Gan, el tamaño de caché codificado de 10 IDENTITY
parece haber cambiado. De los comentarios sobre este elemento de conexión
El tamaño de la preasignación se basa en el tamaño del tipo de datos de la columna en la que se define la propiedad de identidad. Para una columna de enteros de SQL Server, el servidor asigna previamente identidades en rangos de 1000 valores. Para el tipo de datos bigint, el servidor asigna previamente en rangos de 10000 valores.
los libro de consultas de T-SQL contiene la siguiente tabla, pero enfatiza que estos valores no están documentados ni se garantiza que no se modifiquen.
+-----------------+-----------+
| DataType | CacheSize |
+-----------------+-----------+
| TinyInt | 10 |
| SmallInt | 100 |
| Int | 1,000 |
| BigInt, Numeric | 10,000 |
+-----------------+-----------+
El artículo aquí prueba varios tamaños de caché de secuencia e inserta tamaños de lote y ofrece los siguientes resultados.
Lo que parece mostrar que para inserciones grandes IDENTITY
realiza SEQUENCE
. Sin embargo, no prueba el tamaño de caché 1,000 y también esos resultados son solo una prueba. Mirando específicamente el tamaño de caché 1,000 con varios tamaños de lote de insertos, obtuve los siguientes resultados (probando cada tamaño de lote 50 veces y agregando los resultados de la siguiente manera, todo el tiempo en μs).
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
| | Sequence | Identity |
| Batch Size | Min | Max | Avg | Min | Max | Avg |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
| 10 | 2,994 | 7,004 | 4,002 | 3,001 | 7,005 | 4,022 |
| 100 | 3,997 | 5,005 | 4,218 | 4,001 | 5,010 | 4,238 |
| 1,000 | 6,001 | 19,013 | 7,221 | 5,982 | 8,006 | 6,709 |
| 10,000 | 26,999 | 33,022 | 28,645 | 24,015 | 34,022 | 26,114 |
| 100,000 | 189,126 | 293,340 | 205,968 | 165,109 | 234,156 | 173,391 |
| 1,000,000 | 2,208,952 | 2,344,689 | 2,269,297 | 2,058,377 | 2,191,465 | 2,098,552 |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
Para lotes más grandes, el IDENTITY
versión parece generalmente más rápida .
El libro de consulta de TSQL también explica por qué IDENTITY
puede tener una ventaja de rendimiento sobre la secuencia.
La IDENTITY
tabla es específica y SEQUENCE
no lo es. Si el desastre llegara a la mitad de la inserción antes de que se vacíe el búfer de registro, no importa si la identidad recuperada es anterior, ya que el proceso de recuperación también deshacerá la inserción, por lo que SQL Server no fuerza el vaciado del búfer de registro en cada identidad escritura en disco relacionada con caché. Sin embargo, para Secuencia esto se aplica, ya que el valor puede usarse para cualquier propósito, incluso fuera de la base de datos. Entonces, en el ejemplo anterior con un millón de inserciones y un tamaño de caché de 1,000, esto es un adicional de mil descargas de registros.
Script para reproducir
DECLARE @Results TABLE(
BatchCounter INT,
NumRows INT,
SequenceTime BIGINT,
IdTime BIGINT);
DECLARE @NumRows INT = 10,
@BatchCounter INT;
WHILE @NumRows <= 1000000
BEGIN
SET @BatchCounter = 0;
WHILE @BatchCounter <= 50
BEGIN
--Do inserts using Sequence
DECLARE @SequenceTimeStart DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO dbo.t1_Seq1_cache_1000
(c1)
SELECT N
FROM [dbo].[TallyTable] (@NumRows)
OPTION (RECOMPILE);
DECLARE @SequenceTimeEnd DATETIME2(7) = SYSUTCDATETIME();
--Do inserts using IDENTITY
DECLARE @IdTimeStart DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO dbo.t1_identity
(c1)
SELECT N
FROM [dbo].[TallyTable] (@NumRows)
OPTION (RECOMPILE);
DECLARE @IdTimeEnd DATETIME2(7) = SYSUTCDATETIME();
INSERT INTO @Results
SELECT @BatchCounter,
@NumRows,
DATEDIFF(MICROSECOND, @SequenceTimeStart, @SequenceTimeEnd) AS SequenceTime,
DATEDIFF(MICROSECOND, @IdTimeStart, @IdTimeEnd) AS IdTime;
TRUNCATE TABLE dbo.t1_identity;
TRUNCATE TABLE dbo.t1_Seq1_cache_1000;
SET @BatchCounter +=1;
END
SET @NumRows *= 10;
END
SELECT NumRows,
MIN(SequenceTime) AS MinSequenceTime,
MAX(SequenceTime) AS MaxSequenceTime,
AVG(SequenceTime) AS AvgSequenceTime,
MIN(IdTime) AS MinIdentityTime,
MAX(IdTime) AS MaxIdentityTime,
AVG(IdTime) AS AvgIdentityTime
FROM @Results
GROUP BY NumRows;