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

Применимо к:SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

В этой статье описывается, как ядро СУБД реализует сжатие строк. В этой сводке представлены основные сведения, которые помогут при планировании объема хранения.

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

  • Он уменьшает нагрузку на метаданные, связанные с записью. Эти метаданные содержат сведения о столбцах, их длине и смещениях. В некоторых случаях нагрузка на метаданные может быть больше, чем в старом формате хранения.

  • В нем используется переменная длина для числовых типов (например, integer, decimalи float) и для типов, основанных на числовых типах (например, datetime и money).

  • Он сохраняет фиксированные символьные строки, используя формат переменной длины, не сохраняя пустые символы.

Примечание.

NULL и 0 значения для всех типов данных оптимизированы и не принимают байтов.

Влияние сжатия строк на хранилище

В следующей таблице описывается, как сжатие строк влияет на существующие типы в SQL Server и База данных SQL Azure. Таблица не включает экономию, которую можно достичь с помощью сжатия страниц.

Тип данных Изменилось ли хранение? Description
tinyint No 1 байт является минимальным объемом хранения.
smallint Да Если значение соответствует 1 байтам, используется только 1 байт.
int Да Использует минимально необходимое число байт. Например, если значение может храниться в 1 байте, хранилище принимает только 1 байт.
bigint Да Использует минимально необходимое число байт. Например, если значение может храниться в 1 байте, хранилище принимает только 1 байт.
десятичное Да Использует только необходимые байты, независимо от указанной точности. Например, если значение может храниться в 3 байтах, хранилище занимает всего 3 байта. Объем хранилища точно совпадает с форматом хранилища vardecimal .
numeric Да Использует только необходимые байты, независимо от указанной точности. Например, если значение может храниться в 3 байтах, хранилище занимает всего 3 байта. Объем хранилища точно совпадает с форматом хранилища vardecimal .
bit Да Издержки на метаданные приводят это значение к 4 битам.
smallmoney Да Использует целочисленное представление данных с помощью 4-битового целого числа. Значение валюты умножается на 10 000, а итоговое целочисленное значение сохраняется путем удаления всех цифр после десятичной запятой. При хранении этого типа выполняется такая же оптимизация, что и для целочисленных типов.
money Да Использует целочисленное представление данных с помощью 8-битового целого числа. Значение валюты умножается на 10 000, а итоговое целочисленное значение сохраняется путем удаления всех цифр после десятичной запятой. Данный тип имеет больший диапазон, чем smallmoney. При хранении этого типа выполняется такая же оптимизация, что и для целочисленных типов.
float Да Наименее значимые байты с нулями не хранятся. В большинстве случаев для недробных значений в мантиссе применяется сжатиеfloat .
real Да Наименее значимые байты с нулями не хранятся. В большинстве случаев для недробных значений в мантиссе применяется сжатиеreal .
smalldatetime No Использует целочисленное представление данных с помощью двух байтовых целых чисел и является числом дней с момента 1900-01-01. Нет преимущества сжатия строк к дате небольшого времени.

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

Если небольшое время используется только для представления даты (частого случая), время — это 0.0время. При сжатии экономится 2 байта с помощью хранения времени в наиболее значимом байтовом формате для сжатия строки.
datetime Да Использует целочисленное представление данных с использованием четырехбайтных значений. Целочисленное значение представляет количество дней с базовой датой 1900-01-01. Первые 2 байта могут представлять до года 2079. Сжатие может сэкономить 2 байта до этой даты. Каждое целочисленное значение представляет собой 3,33 миллисекунды. Сжатие исчерпывает первые 2 байта в первые пять минут после 4:00, и становится необходимо четыре байта. Таким образом, сжатие может сэкономить только 1 байт после 4:00. Если тип данных datetime сжат, как другие целые числа, сжатие экономит 2 байта в дате.
date No Использует целочисленное представление данных с использованием трехбайтных значений. Это представляет дату из 0001-01-01. Для современных дат сжатие строк использует все 3 байта. При этом экономии не получается.
time No Использует целочисленное представление данных с помощью 3 – 6 байт. Существуют различные точности, начинающиеся с 0 до 9, которые могут занять 3 – 6 байт. Сжатое место используется следующим образом.

Точность = 0. Байт = 3. Каждое целочисленное значение представляет собой одну секунду. Сжатие может представлять время до 18:00, используя 2 байта, потенциально экономя 1 байт.

Точность = 1. Байт = 3. Каждое целочисленное значение представляет собой 1/10 секунды. Сжатие использует третий байт до 2:00. В результате возникает небольшая экономия.

Точность = 2. Байт = 3. Как и в предыдущем случае, вряд ли будет достигнута экономия.

Точность = 3. Байт = 4. Так как первые 3 байта принимают 5AM, этот параметр достигает мало экономии.

Точность = 4. Байт = 4. Первые 3 байта берутся в первые 27 секунд. Экономии не ожидается.

Точность = 5, байты = 5. Пятый байт будет использоваться после 12-полденя.

Точность = 6 и 7, байты = 5. При этом экономии не получается.

Точность = 8, байты = 6. Шестой байт будет использоваться после 3AM.

В хранилище для сжатия строк нет изменений. В целом при сжатии типа данных time может ожидаться небольшая экономия.
datetime2 Да Использует целочисленное представление данных с помощью 6 – 9 байт. Первые 4 байта представляют дату. Байты, принятые временем, зависят от точности указанного времени.

Целочисленное значение представляет количество дней, начиная с 0001-01-01 верхней границы 12/31.9999. Для представления даты в 2005 году сжатие занимает 3 байта.

Нет экономии времени, так как она позволяет 2 – 4 байта для различных точности времени. Таким образом, при точности в одну секунду сжатие использует для времени 2 байта, начиная использовать второй байт после 255 секунд.
datetimeoffset Да Напоминает datetime2, за исключением того, что имеется 2 байта часового пояса формата (HH:mm).

Так же как и для типа datetime2, сжатие может сохранить 2 байта.

Для значений часового пояса mm значение может быть 0 в большинстве случаев. Таким образом, сжатие может сохранить 1 байт.

Изменений в хранении сжатой строки нет.
char Да Конечные символы заполнения удаляются. Ядро СУБД вставляет один и тот же символ заполнения независимо от используемого параметров сортировки.
varchar No Не влияет.
text No Не влияет.
nchar Да 1 Конечные символы заполнения удаляются. Ядро СУБД вставляет один и тот же символ заполнения независимо от используемого параметров сортировки.
nvarchar Нет 1 Не влияет.
ntext No Не влияет.
binary Да Замыкающие нули удаляются.
varbinary No Не влияет.
Изображение No Не влияет.
курсор No Не влияет.
timestamp / rowversion Да Использует целочисленное представление данных с использованием восьмибайтных значений. Существует счетчик меток времени, который поддерживается для каждой базы данных, и его значение начинается с 0. Сжатие возможно и с другими целыми значениями.
sql_variant No Не влияет.
uniqueidentifier No Не влияет.
table No Не влияет.
xml Нет 2 Не влияет.
Определяемые пользователем типы No Имеет внутреннее представление varbinary.
FILESTREAM No Имеет внутреннее представление varbinary.

1 Сжатие Юникода поддерживает типы данных nchar и nvarchar фиксированной длины. Значения данных, хранящиеся вне строки или в столбцах nvarchar(max), не сжимаются. Сжатие Юникода не поддерживается для данных nvarchar(max), даже если он хранится в строке.

2 Внестрочное сжатие данных не сжимается при включении сжатия данных. Например, XML-запись, размер которой превышает 8 060 байт, использует внестровые страницы, которые не сжимаются.