J'ai créé un tableau avec 650 colonnes numériques (19,4). Lorsque j'active la compression de page, en exécutant
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
Je reçois
Msg 1975, Level 16, State 1
Index 'PK_Mytable' la longueur de la ligne dépasse la longueur maximale autorisée de '8060' octets.
mais 650 fois 9 octets n'est que de 5850 octets, ce 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 page?
Voici un 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 des lignes échoue également, mais à un nombre de lignes différent.
sql-server-2016
compression
data-pages
Henrik Staun Poulsen
la source
la source
Réponses:
Si vous essayez de créer votre table sans la contrainte PK en cluster, et vous obtiendrez une erreur légèrement différente:
Dans ce message d'erreur, vous pouvez voir qu'il y a 1530 octets de surcharge interne pour la compression de page.
Maintenant, vous pouvez faire le calcul:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colonnes (5337 octets au total)Donc, 8 + 4 + (593 * 9) + 1530 = 6879. Attendez une seconde .... C'est toujours en dessous de 8060. Qu'est-ce qui se passe?!
L'algorithme de compression de page empile en fait plusieurs algorithmes de compression ensemble. La première étape consiste à appliquer la compression ROW. La surcharge de la compression de ligne n'est pas incluse dans les 1530 octets de surcharge répertoriés dans ce message d'erreur.
Vous pouvez en savoir plus sur le fonctionnement de la compression de lignes ici sur mon blog et ici dans BOL . Vous noterez dans l'article BOL qu'il décrit le
numeric
stockage comme «Ce stockage est exactement le même que le format de stockage vardécimal», mais n'explique pasvardecimal
. Ce message couvrevardecimal
un peu plus - essentiellement, il ajoute 2 octets de surcharge par colonne pour stocker la longueur réelle (similaire à ce qui levarchar
fait).La compression des lignes nécessitera 2 octets supplémentaires pour chacune des 593
numeric
colonnes, plus lebigint
etint
nécessitera 1 octet de surcharge chacun.Les exigences de stockage compressées par ligne seraient les suivantes:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colonnes8 + 4 + (593 * 9) = 5349 octets de données
1 + 1 + (593 * 2) = surcharge de compression de ligne de 1188 octets
6537 octets au total pour le schéma compressé par ligne
Maintenant que nous avons la taille de ligne pour le schéma compressé par ligne, nous pouvons revoir nos calculs. La taille de la ligne compressée sera la taille des données + la surcharge de compression de ligne + la surcharge de compression de page:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colonnes8067 octets au total
la source