He creado una tabla con 650 columnas numéricas (19,4). Cuando enciendo la compresión de página, al ejecutar
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
yo obtengo
Msg 1975, Nivel 16,
Índice de estado 1 La longitud de la fila 'PK_Mytable' excede la longitud máxima permitida de '8060' bytes.
pero 650 veces 9 bytes es solo 5850 bytes, lo cual está bastante lejos del límite establecido de 8060 bytes.
El servidor ejecuta Windows 2012 r2 con SQL Server 2016 SP1 CU2
¿Cuál es la sobrecarga de la fila cuando se usa la compresión de página?
Aquí hay un código para mostrar lo que quiero decir:
/* 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 compresión de filas también falla, pero en un recuento de filas diferente.
sql-server-2016
compression
data-pages
Henrik Staun Poulsen
fuente
fuente
Respuestas:
Si intenta crear su tabla sin la restricción PK agrupada, obtendrá un error ligeramente diferente:
En este mensaje de error, puede ver que hay 1530 bytes de sobrecarga interna para la compresión de la página.
Ahora, puedes hacer los cálculos:
bigint
MyTableIDint
LastColumnnumeric(19,4)
columnas (5337 bytes en total)Entonces, 8 + 4 + (593 * 9) + 1530 = 6879. Espera un segundo ... Eso todavía está por debajo de 8060. ¿Qué pasa con eso?
El algoritmo de compresión de página en realidad apila varios algoritmos de compresión juntos. El primer paso es aplicar compresión ROW. La sobrecarga de la compresión de filas no se incluye en los 1530 bytes de sobrecarga enumerados en ese mensaje de error.
Puede leer más sobre cómo funciona la compresión de filas aquí en mi blog y aquí en BOL .
numeric
Notarás en el artículo de BOL que describe el almacenamiento como "Este almacenamiento es exactamente el mismo que el formato de almacenamiento vardecimal", pero no explicavardecimal
. Esta publicación cubrevardecimal
un poco más, esencialmente, agrega 2 bytes de sobrecarga por columna para almacenar la longitud real (similar a lo quevarchar
hace).La compresión de filas requerirá 2 bytes adicionales para cada una de las 593
numeric
columnas, másbigint
yint
requerirá 1 byte de sobrecarga cada una.Los requisitos de almacenamiento comprimido por filas serían:
bigint
MyTableIDint
Sobrecarga de 4 bytes + 1 byte para LastColumnnumeric(19,4)
columnas8 + 4 + (593 * 9) = 5349 bytes de datos
1 + 1 + (593 * 2) = sobrecarga de compresión de fila de 1188 bytes
6537 bytes en total para el esquema comprimido por filas
Ahora que tenemos el tamaño de fila para el esquema comprimido de fila, podemos volver a ver nuestras matemáticas. El tamaño de fila comprimido por página será el tamaño de datos + sobrecarga de compresión de fila + sobrecarga de compresión de página:
bigint
MyTableIDint
LastColumnnumeric(19,4)
columnas8067 bytes en total
fuente