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

Применяется к:SQL ServerAzure SQL DatabaseAzure, управляемому экземпляру SQL Azure

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

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

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

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

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

Заметка

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

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

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

Тип данных Изменилось ли хранение? 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. Нет преимущества сжатия строк к части даты smalldatetime.

Время представляет количество минут начиная с полуночи. Значения времени, находящиеся немного позже 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 Да Конечные символы заполнения удаляются. Ядро СУБД вставляет один и тот же символ заполнения независимо от используемого параметров сортировки.
nvarchar No Не влияет.
ntext No Не влияет.
binary Да Замыкающие нули удаляются.
varbinary No Не влияет.
Изображение No Не влияет.
курсор No Не влияет.
timestamp / rowversion Да Использует целочисленное представление данных с использованием восьмибайтных значений. Значение счетчика отметок времени поддерживается для каждой базы данных, и это значение начинается с 0. Сжатие возможно и с другими целыми значениями.
sql_variant No Не влияет.
uniqueidentifier No Не влияет.
table No Не влияет.
xml No Не влияет.
Определяемые пользователем типы No Имеет внутреннее представление varbinary.
FILESTREAM No Имеет внутреннее представление varbinary.

Далее