J'ai créé une table avec 650 colonnes numériques (19,4). Lorsque je bascule la compression de la page, en cours d'exécution
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
Je reçois
MSG 1975, niveau 16, état 1
[.____] L'index "Pk_MyTable" La longueur de la ligne dépasse la longueur maximale autorisée des octets '8060'.
mais 650 fois 9 octets ne représentent que 5850 octets, qui est assez loin de la limite indiquée de 8060 octets.
Le serveur exécute Windows 2012 R2 avec SQL Server 2016 SP1 CU2
Quelle est la surcharge de ligne lors de l'utilisation de la compression de la page?
Voici un certain code pour montrer ce que je veux dire:
/* test script to demo MSG 1975 */
DECLARE @sql NVARCHAR(max)='', @i INT =0
drop table if exists dbo.mytable;
SET @sql = 'Create table dbo.Mytable (MyTableID bigint not null
identity(1,1) primary key clustered, '
WHILE @i < 593 BEGIN
SET @sql += ' Column' + LTRIM(@i) + ' numeric(19,4) null, '
SET @i +=1
END
SET @sql += ' LastColumn int) '
--SET @sql += ' with (DATA_COMPRESSION = ROW) '
SET @sql += ' with (DATA_COMPRESSION = PAGE) '
SELECT @sql
EXEC sys.sp_executesql @sql
SELECT top 10000 * FROM dbo.MyTable MT
La compression de ligne échoue également, mais à un nombre de lignes différent.
Si vous essayez de créer votre table sans la contrainte de PK en cluster et que vous obtiendrez une erreur légèrement différente:
MSG 1701, niveau 16, état 1, ligne 1 Création ou modification de la table 'MyTable' a échoué car la taille minimale de la ligne serait de 8067, dont 1530 octets de surcharge interne. Cela dépasse la taille maximale de la rangée de table de table de 8060 octets.
Dans ce message d'erreur, vous pouvez voir qu'il y a 1530 octets de surcharge interne pour la compression de la page.
Maintenant, vous pouvez faire le calcul:
bigint
myTableIDint
lastcolumnnumeric(19,4)
(5337 octets Total)Donc, 8 + 4 + (593 * 9) + 1530 = 6879. Attendez une seconde .... qui est toujours inférieur à 8060. Quoi de neuf avec ça ?!
L'algorithme de compression de la page empile en réalité plusieurs algorithmes de compression ensemble. La première étape consiste à appliquer la compression de ligne. La surcharge de la compression des lignes n'est pas incluse dans les 1530 octets de la surcharge répertoriée dans ce message d'erreur.
Vous pouvez en savoir plus sur la fonction de compression de ligne ici sur mon blog et ici dans Bol . Vous noterez dans l'article BOL qu'il décrit le stockage numeric
_ STOCKS comme "Ce stockage est exactement comme le format de stockage Vardecimal", mais n'explique pas vardecimal
. ce post Couvre vardecimal
Un peu plus - essentiellement, il ajoute 2 octets de surcharge par colonne pour stocker la longueur réelle (similaire à ce que varchar
fait).
La compression de lignes nécessitera 2 octets supplémentaires pour chacune des colonnes 593 numeric
, plus le bigint
et int
_ _ _ _ _ _ _ _ _ _ _ _ _ _ era nécessitera 1 octet de la tête de charge.
Le Les exigences de stockage compressées de ligne seraient les suivantes:
bigint
myTableIDint
lastcolumnnumeric(19,4)
Colonnes8 + 4 + (593 * 9) = 5349 Bytes Données
1 + 1 + (593 * 2) = 1188 octets de compression des rangées
6537 octets totale pour le schéma compressé de ligne
Maintenant que nous avons la taille de la ligne pour le schéma compressé de la ligne, nous pouvons revisiter nos mathématiques. La taille de la ligne compressée de la page sera la taille de données + la compression de la ligne de compression + la page de compression de la page:
bigint
myTableIDint
lastcolumnnumeric(19,4)
colonnes[