Eu tenho uma tabela de log genérica, com cerca de 5m de linhas.
Há um campo de "digitação forte" que armazena o tipo de evento e várias colunas de "digitação imprecisa" que contêm dados relevantes para o evento. Ou seja, o significado dessas colunas "digitadas imprecisamente" depende do tipo de 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, poucos tipos de evento forneceriam tanta informação. Portanto, decidi 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 são null
. De acordo com a tabela de limite de economia de 40% , SPARSE
seria uma grande vitória para eles.
Então eu fui e apliquei SPARSE
nas colunas 3-5 em cada grupo. Agora, minha tabela ocupa cerca de 1,8 Gb no espaço de dados, conforme relatado por sp_spaceused
, enquanto antes do sparsing era de 1 Gb.
Eu tentei dbcc cleantable
, mas não teve efeito.
Então dbcc shrinkdatabase
, nenhum efeito também.
Intrigado, removi SPARSE
e repeti o dbcc
s. O tamanho da mesa permaneceu em 1,8 Gb.
O que da?
Você precisa reconstruir o índice clusterizado depois de tornar as colunas esparsas. As colunas descartadas ainda existem na página de dados até que você faça isso, como pode ser visto com uma consulta
sys.system_internals_partition_columns
ou usandoDBCC PAGE