SQL Server 2008 – Сжатие данных

        Ну вот я и попробовал сжатие на реальной системе и на реальных базах данных. Пару слов о том, что это такое и переходим к делу. Компрессия данных появилась в SQL Server 2008 и  со стороны её можно представить в виде айсберга. На верхушке которого – уменьшение занимаемого дискового пространства, а скрыто от глаз ещё более интересное преимущество – снижение нагрузки на ввод/вывод за счёт меньшего количества читаемых данных. Ну и конечно же, не могу обойти стороной один не очень хороший момент – увеличение нагрузки на CPU, но без этого никак. Более того, сам алгоритм сжатия данных не преследует цель максимально зажать данные, а призван соблюдать разумный баланс между процентом сжатия данных и затратами на упаковку/распаковку данных. Сжатие работает в двух режимах: Row Compression и Page Compression. И в своём посте я расскажу о том как и насколько я зажал данные реальных баз и как это сказалось на работе приложений.

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

ALTER TABLE Test REBUILD WITH (DATA_COMPRESSION = PAGE);
GO

       В этом случае будет сжат либо кластерный индекс таблицы (если он есть) либо данные таблицы хранящиеся в куче. Здесь нужно помнить, что некластерные индексы не будут сжаты в этом случае. А при использовании индексов с конструкцией INCLUDE это может быть довольно значительный объём данных. Более подробно о сжатии таблиц, индексов и различных аспектов, связанных со сжатием можно почитать здесь - Создание сжатых таблиц и индексов. Я же хочу показать свой вариант сжатия всей базы данных одним махом Smile Для этого я использую недокументированную процедуру sp_MSforeachtable (вместо символа вопроса хранимка подставляет имя таблицы, таким образом код выполняется для всех таблиц в базе данных):

EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REBUILD WITH (DATA_COMPRESSION = PAGE)'
GO

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

        Посмотреть фактический объём данных базы можно при помощи следующего скрипта:

CREATE TABLE #t (name SYSNAME, rows CHAR(11), reserved VARCHAR(18),  
data VARCHAR(18), index_size VARCHAR(18), unused VARCHAR(18))

EXEC sp_msforeachtable 'INSERT INTO #t EXEC sp_spaceused ''?'''

SELECT SUM(CONVERT(INT, SUBSTRING(data, 1, LEN(data)-3))) FROM #t
DROP TABLE #t

       Запустив этот скрипт до и после компрессии, можно посмотреть эффект, произведённый сжатием. На моих базах (размером от 10-и до 50 Гб) объём данных уменьшился примерно на одну четвёртую. Также вы может сделать замеры показателей использования CPU и памяти в моменты нагрузки системы и сравнить их с показателями до включения сжатия. Напоследок хочу сказать, что недостатков  включения компрессии я не почувствовал, только преимущества Smile. Система работает стабильно уже на протяжении нескольких недель, что не может не радовать Smile Но в то же время, на нашем сервере, на котором стоит сиквел, процессор используется далеко не по полной. И я бы не рекомендовал рисковать и включать компрессию на системах с дефицитом процессорного времени.

 

Ссылки по теме:

- Создание сжатых таблиц и индексов

- Реализация сжатия строк

- Реализация сжатия страниц

- Data Compression: Why Do we need it?

- Сжатие в Microsoft SQL Server 2008

blog comments powered by Disqus

Обо мне

MVP

Data Architect at Intapp, Inc.

PASS Regional Mentor, CEE

MCT, MCITP, MCPD, MCTS


Microsoft MVP

Month List