web-dev-qa-db-fra.com

Quelle est la surcharge de ligne lors de l'utilisation de la compression de la page?

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.

10

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:

  • 8 octets pour bigint myTableID
  • 4 octets pour int lastcolumn
  • 9 octets pour chacune des colonnes 593 numeric(19,4) (5337 octets Total)
  • 1530 octets de la surcharge de compression

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:

  • 8 octets + 1 octet surhead pour bigint myTableID
  • 4 octets + 1 surcharge d'octets pour int lastcolumn
  • 9 octets + 2 octets surhead pour chacune des colonnes 593 numeric(19,4) Colonnes
  • 1188 octets de la compression de rangée

8 + 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:

  • 8 octets pour bigint myTableID
  • 4 octets pour int lastcolumn
  • 9 octets pour chacun des 593 numeric(19,4) colonnes
  • 1188 octets de la compression de rangée
  • 1530 octets de la page de compression de page
[

8067 octets Total

13
AMtwo