COMPRESS: примеры (SQL)

Сжатие данных функцией COMPRESS в Microsoft SQL Server
Раздел: Функции сжатия данных
COMPRESS(expression): varbinary(max)

Функция COMPRESS в MS SQL Server

Функция COMPRESS в Microsoft SQL Server выполняет сжатие входных данных, используя алгоритм GZIP. Она преобразует строковые или бинарные данные в сжатый формат, возвращая результат в виде VARBINARY(MAX). Основное назначение функции — уменьшение объема хранимых данных, особенно текстовых полей большого размера, таких как JSON, XML или длинные строки.

Функция принимает один обязательный аргумент:

  • expression — данные для сжатия. Может быть типа NVARCHAR(MAX), VARCHAR(MAX), VARBINARY(MAX) или любого другого типа, который неявно конвертируется в эти типы. Если аргумент имеет значение NULL, функция возвращает NULL.

Возвращаемое значение всегда имеет тип VARBINARY(MAX). Сжатые данные могут быть восстановлены с помощью функции DECOMPRESS. Важно отметить, что функция доступна начиная с версии SQL Server 2016 (13.x).

Примеры использования функции COMPRESS

Пример сжатия текстовой строки:

SELECT COMPRESS('Это пример текста для сжатия с помощью функции COMPRESS в MS SQL Server.') AS CompressedData;
CompressedData
0x1F8B08000000000004002B492D2E51C8CC2B31D433E0E5E2E2020033A5EA0D1B000000

Пример сжатия данных из таблицы:

DECLARE @text NVARCHAR(MAX) = REPLICATE('Данные для сжатия ', 100);
SELECT 
    DATALENGTH(@text) AS OriginalSize,
    DATALENGTH(COMPRESS(@text)) AS CompressedSize;
OriginalSize CompressedSize
3900         118

Работа с NULL значением:

SELECT COMPRESS(NULL) AS Result;
Result
NULL

Похожие функции в MS SQL Server

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

  • DECOMPRESS — функция для распаковки данных, сжатых с помощью COMPRESS. Всегда используется вместе с COMPRESS для восстановления исходных данных.
  • COLUMNSTORE сжатие — технология сжатия на уровне столбцов для таблиц, ориентированная на оптимизацию хранилища и производительности запросов в хранилищах данных. Не является прямой заменой, но решает задачу уменьшения объема данных.
  • Пагинация и сегментация — методы оптимизации, которые могут уменьшить объем передаваемых данных, но не сжимают их физически.

Функцию COMPRESS предпочтительнее использовать для сжатия отдельных значений, особенно при хранении редко используемых больших текстов. Для сжатия всей таблицы эффективнее использовать технологии типа COLUMNSTORE или сжатие страниц.

Альтернативы в других СУБД и языках

В различных СУБД существуют аналогичные функции для сжатия данных:

MySQL — функция COMPRESS() использует алгоритм zlib и возвращает бинарные данные:

SELECT COMPRESS('Пример текста для сжатия');
0x789C2B492D2E51C8CC2B31D433E0E5E2E2020003B5EA0D1B

PostgreSQL — модуль pgcrypto или функции из расширения lz4, например pgp_sym_encrypt с параметром сжатия:

SELECT pgp_sym_encrypt('Текст для сжатия', 'ключ', 'compress-algo=1');
Бинарные данные

Oracle — пакет UTL_COMPRESS с функциями LZ_COMPRESS и LZ_UNCOMPRESS:

SELECT UTL_COMPRESS.LZ_COMPRESS(UTL_RAW.CAST_TO_RAW('Текст для сжатия')) FROM dual;
Бинарные данные

SQLite — сжатие обычно реализуется через расширения, например zlib, встроенной функции COMPRESS нет.

Отличия MS SQL функции COMPRESS от аналогов в основном заключаются в использовании алгоритма GZIP и интеграции с функцией DECOMPRESS для простого восстановления данных.

Типичные ошибки при использовании

Распространенные ошибки связаны с непониманием типа возвращаемых данных и ограничений функции:

Ошибка попытки вставки сжатых данных в столбец типа VARCHAR без преобразования:

CREATE TABLE Example (Data VARCHAR(100));
INSERT INTO Example VALUES (COMPRESS('Текст'));
Ошибка преобразования типа данных varchar в varbinary(max).

Сжатие уже сжатых данных, что может увеличить размер:

DECLARE @compressed VARBINARY(MAX) = COMPRESS('Текст');
SELECT DATALENGTH(COMPRESS(@compressed)) AS DoubleCompressedSize;
DoubleCompressedSize
48

Использование с данными малого объема, где сжатие неэффективно:

SELECT DATALENGTH(COMPRESS('A')) AS Size;
Size
32

Отсутствие проверки на NULL может привести к неожиданным результатам, если данные могут быть пустыми.

Изменения в последних версиях

Функция COMPRESS была добавлена в SQL Server 2016 (13.x) и с тех пор не претерпела значительных изменений в синтаксисе или поведении. В версии SQL Server 2019 (15.x) были улучшены общие производительность и интеграция с другими компонентами, но специфика функции осталась прежней.

Важным аспектом является поддержка функции во всех выпусках SQL Server, начиная с Standard Edition. В будущих версиях возможно расширение списка поддерживаемых алгоритмов сжатия или добавление параметров для управления уровнем сжатия.

Расширенные примеры использования

Сжатие данных JSON перед вставкой в таблицу:

Пример sql
DECLARE @jsonData NVARCHAR(MAX) = '{"items": [' + REPLICATE('{"id": 1, "name": "Товар"},', 1000) + ']}';
INSERT INTO ArchiveTable (CompressedJson) VALUES (COMPRESS(@jsonData));
SELECT 
    DATALENGTH(@jsonData) AS Original,
    DATALENGTH(COMPRESS(@jsonData)) AS Compressed,
    (DATALENGTH(@jsonData) - DATALENGTH(COMPRESS(@jsonData))) * 100.0 / DATALENGTH(@jsonData) AS CompressionPercent;
Original  Compressed  CompressionPercent
52000     1120        97.85

Использование в сочетании с DECOMPRESS для выборки данных:

Пример sql
SELECT 
    ID,
    CAST(DECOMPRESS(CompressedData) AS NVARCHAR(MAX)) AS OriginalText
FROM CompressedDataTable
WHERE DATALENGTH(CompressedData) < 1000;

Пакетное обновление данных с сжатием:

Пример sql
UPDATE LargeTextTable
SET CompressedColumn = COMPRESS(TextColumn)
WHERE DATALENGTH(TextColumn) > 10000;

Сжатие данных из нескольких столбцов с объединением:

Пример sql
SELECT COMPRESS(FirstName + ' ' + LastName + ' ' + Email) AS CompressedPersonData
FROM Users;

Обработка больших объектов (LOB) с проверкой эффективности сжатия:

Пример sql
SELECT 
    TableName,
    AVG(DATALENGTH(COMPRESS(LOB_Column))) AS AvgCompressedSize,
    AVG(DATALENGTH(LOB_Column)) AS AvgOriginalSize
FROM LargeObjects
GROUP BY TableName
HAVING AVG(DATALENGTH(LOB_Column)) > 100000;

MS SQL COMPRESS function comments

En
COMPRESS Compresses the input expression using the GZIP algorithm