Eu tenho uma tabela de log genérica, com cerca de 5m de linhas.
Há um campo "fortemente tipado" que armazena o tipo de evento e várias colunas "mal tipadas" que contêm dados relevantes para o evento. Ou seja, o significado dessas colunas "com tipagem incorreta" depende do tipo do evento.
Essas colunas são definidas como:
USER_CHAR1 nvarchar(150) null,
USER_CHAR2 nvarchar(150) null,
USER_CHAR3 nvarchar(150) null,
USER_CHAR4 nvarchar(150) null,
USER_CHAR5 nvarchar(150) null,
USER_INTEGER1 int null,
USER_INTEGER2 int null,
USER_INTEGER3 int null,
USER_INTEGER4 int null,
USER_INTEGER5 int null,
USER_FLAG1 bit null,
USER_FLAG2 bit null,
USER_FLAG3 bit null,
USER_FLAG4 bit null,
USER_FLAG5 bit null,
USER_FLOAT1 float null,
USER_FLOAT2 float null,
USER_FLOAT3 float null,
USER_FLOAT4 float null,
USER_FLOAT5 float null
As colunas 1 e 2 em cada tipo são muito usadas, mas a partir do número 3, muito poucos tipos de eventos forneceriam tanta informação. Por isso, desejei marcar as colunas 3-5 em cada tipo como SPARSE
.
Fiz algumas análises primeiro e vi que, de fato, pelo menos 80% dos dados em cada uma dessas colunas são null
e em cerca de 100% dos dados null
. De acordo com a tabela de limiar de economia de 40% , SPARSE
seria uma grande vitória para eles.
Então, fui e me inscrevi SPARSE
nas colunas 3-5 de cada grupo. Agora, minha tabela ocupa cerca de 1,8 Gb no espaço de dados, conforme relatado por sp_spaceused
, enquanto antes era poupado 1 Gb.
Eu tentei dbcc cleantable
, mas não teve efeito.
Então dbcc shrinkdatabase
, também não tem efeito.
Intrigado, retirei SPARSE
e repeti os dbcc
s. O tamanho da tabela permaneceu em 1,8 Gb.
O que da?
rowid int not null identity(1,1) primary key clustered
.Respostas:
Você precisa recriar o índice em cluster depois de tornar as colunas esparsas. As colunas descartadas ainda existem na página de dados até você fazer isso como pode ser visto com uma consulta
sys.system_internals_partition_columns
ou usandoDBCC PAGE
fonte