вторник, 4 декабря 2018 г.

Сжимаем ииии разжимаем. Compressed and uncompressed.


В MS SQL Server есть возможность сжатия данных на уровне строк или на уровне страниц.
Информация по данной возможности описана на страницах Microsoft:
В текущей заметке хочу остановиться не на описание технологий и плюсах и минуса, а о некоторой особенности, которую необходимо знать при включении сжатия. 


Многие администраторы или разработчики включают данное сжатие на таблице\секциях и думают, что получили весь профит от сжатия, при этом таблица\секции продолжает дальше жить, наполняться данными.
К примеру, создали таблицу и включили сжатие данных, таблица\секции еще без данных , или данных не много, они будут заливаться в процессе работы:

После этого база данных живет, таблица наполняется данными. Для примера я приведу результаты моей таблицы архивных данных:
-  первая таблица результат загруженных данных в пустую секцию с включенным сжатием
-  вторая таблица результат расзжатия этой же таблицы\секции
-  и третья таблица, повторное сжатие секций этих же данных.

Как видим, включение сжатие на пустой таблице дает результат сжатия, размер секций меньше секций без включенного сжатия, но максимальное сжатие можно получить, если сжать эти же секции еще раз.
Так что сжимайте и разжимайте секции, благо все делается с параметром ONLINE=ON.

Второй вопрос, который я бы хотел упомянуть про сжатие, что по умолчанию сжатие таблицы это сжатие клатерного индекса, но сжать можно и некластерные индексы.
К примеру, созадим таблицу и два индекса на ней, кластерный и некластерный:

CREATE TABLE [dbo].[Tbl_test](
       [id] [int] NOT NULL,
       [val] [nchar](10) NOT NULL,
 CONSTRAINT [PK_Tbl_test] PRIMARY KEY CLUSTERED
(
       [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
CREATE NONCLUSTERED INDEX [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

Далее включим сжатие, либо командой:

ALTER TABLE [dbo].[Tbl_test] REBUILD PARTITION = ALL
WITH (DATA_COMPRESSION = PAGE)


Либо графически, что для некоторых удобно:

что одно и тоже с командой выше. После этого мы думаем, что сжатие включено, но если посмотреть на данные, то не все так  есть:

select  object_name(p.object_id) as TblName,i.name,p.data_compression_desc
from sys.partitions  p
       inner join sys.indexes i on p.object_id=i.object_id and i.index_id=p.index_id
where p.object_id=object_id('[dbo].[Tbl_test]')
order by i.index_id asc

TblName
name
data_compression_desc
Tbl_test
PK_Tbl_test
PAGE
Tbl_test
NonClusteredIndex_val
NONE

Сжатым оказался только кластерный индекс, некластерный индекс не сжат. Некластерный сжимается отдельно командой ALTER

USE [TestDb]
ALTER INDEX [NonClusteredIndex_val] on [dbo].[Tbl_test] REBUILD PARTITION = 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)для каждой таблицы нужны выбирать индивидуально и желательно только через реальный тест, а не предварительный расчет студии, уже не буду упоминать. Иногда предварительный выигрыш показывает, а реальный выигрыш очень небольшой по сравнению потраченными ресурсами и наоборот.

Комментариев нет :

Отправить комментарий