He creado la siguiente tabla:
CREATE TABLE dbo.TestStructure
(
id INT NOT NULL,
filler1 CHAR(36) NOT NULL,
filler2 CHAR(216) NOT NULL
);
y luego creó un índice agrupado:
CREATE CLUSTERED INDEX idx_cl_id
ON dbo.TestStructure(id);
Luego lo rellené con 30 filas cada tamaño es de 256 bytes (según la declaración de la tabla):
DECLARE @i AS int = 0;
WHILE @i < 30
BEGIN
SET @i = @i + 1;
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (@i, 'a', 'b');
END;
Ahora, según la información que leí en el libro "Kit de capacitación (examen 70-461): Consulta de Microsoft SQL Server 2012 (Itzik Ben-Gan)":
SQL Server organiza internamente los datos en un archivo de datos en páginas. Una página es una unidad de 8 KB y pertenece a un solo objeto; por ejemplo, a una tabla o un índice. Una página es la unidad más pequeña de lectura y escritura. Las páginas se organizan en extensiones. Una extensión consta de ocho páginas consecutivas. Las páginas de una extensión pueden pertenecer a un solo objeto o a varios objetos. Si las páginas pertenecen a varios objetos, la extensión se denomina extensión mixta; Si las páginas pertenecen a un solo objeto, la extensión se denomina extensión uniforme. SQL Server almacena las primeras ocho páginas de un objeto en extensiones mixtas. Cuando un objeto excede las ocho páginas, SQL Server asigna extensiones uniformes adicionales para este objeto. Con esta organización, los objetos pequeños desperdician menos espacio y los objetos grandes están menos fragmentados.
Así que aquí tengo la primera página de 8 KB de extensión mixta, poblada con 7680 bytes (he insertado 30 veces la fila de 256 bytes de tamaño, por lo que 30 * 256 = 7680), para verificar el tamaño que he ejecutado, compruebe el tamaño del proceso: devuelve el siguiente resultado
index_type_desc: CLUSTERED INDEX
index_depth: 1
index_level: 0
page_count: 1
record_count: 30
avg_page_space_used_in_percent: 98.1961947121324
name : TestStructure
rows : 30
reserved : 16 KB
data : 8 KB
index_size : 8 KB
unused : 0 KB
Entonces, 16 KB están reservados para la tabla, la primera página de 8 KB es para la página Root IAM, la segunda es para la página de almacenamiento de datos de hoja que es de 8 KB con una ocupación de ~ 7.5 KB, ahora cuando inserto una nueva fila con 256 Byte:
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');
no se almacena en la misma página, aunque tiene un espacio de 256 bytes (7680 b + 256 = 7936, que aún es más pequeño que 8 KB), se crea una nueva página de datos, pero esa nueva fila podría caber en la misma página anterior , ¿por qué SQL Server crea una nueva página cuando podría ahorrar espacio y tiempo de búsqueda al insertarla en la página existente?
Nota: lo mismo está sucediendo en el índice de montón.