Mam ogólną tabelę dziennika, około 5m wierszy.
Istnieje pole „silnie typowane”, które przechowuje typ zdarzenia, oraz kilka kolumn „luźno typowanych”, które zawierają dane istotne dla zdarzenia. Oznacza to, że znaczenie tych „luźno wpisanych” kolumn zależy od typu zdarzenia.
Te kolumny są zdefiniowane jako:
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
Kolumny 1 i 2 w każdym typie są intensywnie używane, ale począwszy od liczby 3, bardzo niewiele typów zdarzeń zapewniłoby tyle informacji. Dlatego postanowiłem oznaczyć kolumny 3-5 w każdym typie jako SPARSE
.
Najpierw dokonałem analizy i zobaczyłem, że rzeczywiście co najmniej 80% danych w każdej z tych kolumn jest null
, a około 100% danych null
. Według 40% Tabela progowej oszczędności , SPARSE
byłby to ogromny wygrana na nich.
Poszedłem i zastosowałem się SPARSE
do kolumn 3-5 w każdej grupie. Teraz moja tabela zajmuje około 1,8 Gb w przestrzeni danych, jak donosi sp_spaceused
, podczas gdy przed sparowaniem była to 1 Gb.
Próbowałem dbcc cleantable
, ale nie przyniosło to efektu.
Wtedy też dbcc shrinkdatabase
nie ma żadnego efektu.
Zdziwiony usunąłem SPARSE
i powtórzyłem dbcc
s. Rozmiar tabeli pozostał na poziomie 1,8 Gb.
Co daje?
rowid int not null identity(1,1) primary key clustered
.Odpowiedzi:
Musisz odbudować indeks klastrowany po zmniejszeniu liczby kolumn. Upuszczone kolumny nadal istnieją na stronie danych, dopóki nie zrobisz tego, co można zobaczyć po zapytaniu przeciwko
sys.system_internals_partition_columns
lub użyciuDBCC PAGE
źródło