J'ai créé le tableau suivant:
CREATE TABLE dbo.TestStructure
(
id INT NOT NULL,
filler1 CHAR(36) NOT NULL,
filler2 CHAR(216) NOT NULL
);
puis créé un index clusterisé:
CREATE CLUSTERED INDEX idx_cl_id
ON dbo.TestStructure(id);
Ensuite, je l'ai rempli avec 30 lignes, chaque taille est de 256 octets (basée sur la déclaration de la table):
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;
Maintenant basé sur les informations que j'ai lues dans le livre "Kit de formation (examen 70-461): Interrogation de Microsoft SQL Server 2012 (Itzik Ben-Gan)":
SQL Server organise en interne les données dans un fichier de données en pages. Une page est une unité de 8 Ko et appartient à un seul objet; par exemple, vers une table ou un index. Une page est la plus petite unité de lecture et d'écriture. Les pages sont en outre organisées en étendues. Une étendue se compose de huit pages consécutives. Les pages d'une étendue peuvent appartenir à un seul objet ou à plusieurs objets. Si les pages appartiennent à plusieurs objets, l'extension est appelée extension mixte; si les pages appartiennent à un seul objet, alors l'étendue est appelée une étendue uniforme. SQL Server stocke les huit premières pages d'un objet dans des extensions mixtes. Lorsqu'un objet dépasse huit pages, SQL Server alloue des extensions uniformes supplémentaires pour cet objet. Avec cette organisation, les petits objets perdent moins d'espace et les gros objets sont moins fragmentés.
J'ai donc ici la première page d'étendue mixte de 8 Ko, remplie de 7680 octets (j'ai inséré 30 fois la ligne de taille de 256 octets, donc 30 * 256 = 7680), pour vérifier la taille, j'ai exécuté la vérification de la taille proc - elle renvoie le résultat suivant
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
Donc 16 Ko sont réservés pour la table, la première page de 8 Ko est pour la page Root IAM, la seconde est pour la page de stockage de données feuille qui est de 8 Ko avec une occupation de ~ 7,5 Ko, maintenant lorsque j'insère une nouvelle ligne avec 256 octets:
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');
il n'est pas stocké dans la même page bien qu'il ait un espace de 256 octets (7680 b + 256 = 7936 qui est encore plus petit que 8 Ko), une nouvelle page de données est créée, mais cette nouvelle ligne pourrait tenir sur la même ancienne page , pourquoi SQL Server crée-t-il une nouvelle page alors qu'il peut économiser de l'espace et du temps de recherche en l'insérant dans la page existante?
Remarque: la même chose se produit dans l'index de tas.