Eu criei uma tabela com 650 colunas numéricas (19,4). Quando ligo a compactação de página, executando
ALTER TABLE fct.MyTable REBUILD WITH (DATA_COMPRESSION = PAGE);
eu recebo
Mensagem 1975, Nível 16, Estado 1
O comprimento da linha do índice 'PK_Mytable' excede o comprimento máximo permitido de bytes '8060'.
mas 650 vezes 9 bytes são apenas 5850 bytes, o que está muito longe do limite declarado de 8060 bytes.
O servidor está executando o Windows 2012 r2 com o SQL Server 2016 SP1 CU2
Qual é a sobrecarga da linha ao usar a compactação de página?
Aqui está um código para mostrar o que quero dizer:
/* 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
A compactação de linha também falha, mas com uma contagem de linhas diferente.
sql-server-2016
compression
data-pages
Henrik Staun Poulsen
fonte
fonte
Respostas:
Se você tentar criar sua tabela sem a restrição PK em cluster e obterá um erro ligeiramente diferente:
Nesta mensagem de erro, você pode ver que há 1530 bytes de sobrecarga interna para compactação de página.
Agora, você pode fazer as contas:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colunas (5337 bytes no total)Então, 8 + 4 + (593 * 9) + 1530 = 6879. Espere um segundo ... Ainda está abaixo de 8060. O que há com isso ?!
O algoritmo de compactação de página realmente empilha vários algoritmos de compactação juntos. O primeiro passo é aplicar a compressão ROW. A sobrecarga da compactação de linha não está incluída nos 1530 bytes de sobrecarga listados nessa mensagem de erro.
Você pode ler mais sobre como a compactação de linhas funciona aqui no meu blog e aqui no BOL . Você observará no artigo da BOL que descreve o
numeric
armazenamento como "Este armazenamento é exatamente igual ao formato de armazenamento vardecimal", mas não explicavardecimal
. Este post abordavardecimal
um pouco mais - essencialmente, ele adiciona 2 bytes de sobrecarga por coluna para armazenar o comprimento real (semelhante ao quevarchar
faz).A compactação de linha exigirá 2 bytes adicionais para cada uma das 593
numeric
colunas, mais obigint
eint
exigirá 1 byte de sobrecarga cada.Os requisitos de armazenamento compactado em linha seriam:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colunas8 + 4 + (593 * 9) = 5349 bytes de dados
1 + 1 + (593 * 2) = 1188 bytes de sobrecarga de compactação de linha
6537 bytes no total para esquema compactado em linha
Agora que temos o tamanho da linha para o esquema compactado, podemos revisar nossa matemática. O tamanho da linha compactada na página será o tamanho dos dados + sobrecarga de compactação de linha + sobrecarga de compactação de página:
bigint
MyTableIDint
LastColumnnumeric(19,4)
colunas8067 bytes no total
fonte