В MSSQLServerесть возможность сжатия данных на уровне строк или на уровне страниц.
Информация по данной возможности описана на страницах Microsoft:
В текущей заметке хочу остановиться не на описание технологий и плюсах и минуса, а о некоторой особенности, которую необходимо знать при включении сжатия.
Многие администраторы или разработчики включают данное сжатие на таблице\секциях и думают, что получили весь профит от сжатия, при этом таблица\секции продолжает дальше жить, наполняться данными.
К примеру, создали таблицу и включили сжатие данных, таблица\секции еще без данных , или данных не много, они будут заливаться в процессе работы:После этого база данных живет, таблица наполняется данными. Для примера я приведу результаты моей таблицы архивных данных:
- первая таблица результат загруженных данных в пустую секцию с включенным сжатием
- вторая таблица результат расзжатия этой же таблицы\секции
- и третья таблица, повторное сжатие секций этих же данных.
Так что сжимайте и разжимайте секции, благо все делается с параметром ONLINE=ON.
Второй вопрос, который я бы хотел упомянуть про сжатие, что по умолчанию сжатие таблицы это сжатие клатерного индекса, но сжать можно и некластерные индексы.
К примеру, созадим таблицу и два индекса на ней, кластерный и некластерный:
CREATETABLE [dbo].[Tbl_test](
[id] [int] NOTNULL,
[val] [nchar](10)NOTNULL,
CONSTRAINT [PK_Tbl_test] PRIMARYKEYCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX=OFF,STATISTICS_NORECOMPUTE=OFF,IGNORE_DUP_KEY=OFF,
ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON)ON [PRIMARY]
)ON [PRIMARY]
GO
CREATENONCLUSTEREDINDEX [NonClusteredIndex_val] ON [dbo].[Tbl_test]
(
[val] ASC
)WITH (PAD_INDEX=OFF,STATISTICS_NORECOMPUTE=OFF,SORT_IN_TEMPDB=OFF,DROP_EXISTING=OFF, OLINE=OFF,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON)ON [PRIMARY]
GO
Далее включим сжатие, либо командой:
ALTERTABLE [dbo].[Tbl_test] REBUILDPARTITION=ALL
WITH (DATA_COMPRESSION=PAGE)
Либо графически, что для некоторых удобно:
что одно и тоже с командой выше. После этого мы думаем, что сжатие включено, но если посмотреть на данные, то не все так есть:
select object_name(p.object_id)as TblName,i.name,p.data_compression_desc
fromsys.partitions p
innerjoinsys.indexes i on p.object_id=i.object_idand i.index_id=p.index_id
where p.object_id=object_id('[dbo].[Tbl_test]')
orderby i.index_id asc
TblName | name | data_compression_desc |
Tbl_test | PK_Tbl_test | PAGE |
Tbl_test | NonClusteredIndex_val | NONE |
Сжатым оказался только кластерный индекс, некластерный индекс не сжат. Некластерный сжимается отдельно командой ALTER
USE [TestDb]
ALTERINDEX[NonClusteredIndex_val] on [dbo].[Tbl_test] REBUILDPARTITION=ALL
WITH (DATA_COMPRESSION=PAGE)
После этого таблица полностью сжата:
TblName | name | data_compression_desc |
Tbl_test | PK_Tbl_test | PAGE |
Tbl_test | NonClusteredIndex_val | PAGE |
Так что проверьте, все ли у вас сжато!
Удачного сжатия и разжатия!
P.S.:
Ну про то, что тип сжатия (ROW или PAGE)для каждой таблицы нужны выбирать индивидуально и желательно только через реальный тест, а не предварительный расчет студии, уже не буду упоминать. Иногда предварительный выигрыш показывает, а реальный выигрыш очень небольшой по сравнению потраченными ресурсами и наоборот.