Eu criei a seguinte tabela:
CREATE TABLE dbo.TestStructure
(
id INT NOT NULL,
filler1 CHAR(36) NOT NULL,
filler2 CHAR(216) NOT NULL
);
e, em seguida, criou um índice em cluster:
CREATE CLUSTERED INDEX idx_cl_id
ON dbo.TestStructure(id);
Em seguida, preenchi-o com 30 linhas, cada tamanho com 256 bytes (com base na declaração da tabela):
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;
Agora, com base nas informações que li no "Kit de treinamento (Exame 70-461): Consultando o Microsoft SQL Server 2012 (Itzik Ben-Gan)" no livro:
O SQL Server organiza internamente os dados em um arquivo de dados em páginas. Uma página é uma unidade de 8 KB e pertence a um único objeto; por exemplo, para uma tabela ou um índice. Uma página é a menor unidade de leitura e escrita. As páginas são organizadas em extensão. Uma extensão consiste em oito páginas consecutivas. As páginas de uma extensão podem pertencer a um único objeto ou a vários objetos. Se as páginas pertencerem a vários objetos, a extensão será chamada de extensão mista; se as páginas pertencerem a um único objeto, a extensão será chamada de extensão uniforme. O SQL Server armazena as oito primeiras páginas de um objeto em extensões mistas. Quando um objeto excede oito páginas, o SQL Server aloca extensões uniformes adicionais para esse objeto. Com essa organização, objetos pequenos desperdiçam menos espaço e objetos grandes são menos fragmentados.
Portanto, aqui tenho a primeira página de 8 KB de extensão mista, preenchida com 7680 bytes (inseri uma linha de tamanho de 30 vezes 256 bytes, portanto, 30 * 256 = 7680), para verificar o tamanho em que corri proc de verificação de tamanho - ele retorna o seguinte 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
Portanto, 16 KB são reservados para a tabela, a primeira página de 8 KB é para a página Root IAM, a segunda é para a página de armazenamento de dados em folha, com 8 KB com ocupação de ~ 7,5 KB, agora quando insiro uma nova linha com 256 bytes:
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');
ele não é armazenado na mesma página, embora tenha um espaço de 256 bytes (7680 b + 256 = 7936, que ainda é menor que 8 KB), uma nova página de dados é criada, mas essa nova linha pode caber na mesma página antiga , por que o SQL Server cria uma nova página quando pode economizar espaço e tempo de pesquisa, inserindo-a na página existente?
Nota: o mesmo está acontecendo no índice de heap.