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

Этот раздел содержит описание того, как компонент Database Engine реализует сжатие строки. В этой сводке представлены основные сведения, которые помогут при планировании объема хранения.

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

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

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

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

ПримечаниеПримечание

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

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

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

Тип данных

Изменилось ли хранение?

Описание

tinyint

Нет

1 байт является минимальным объемом хранения.

smallint

Да

Если значение соответствует 1 байту, то будет использован только 1 байт.

int

Да

Использует минимально необходимое число байт. Например, если значение может храниться в 1 байте, то для его хранения будет использоваться всего 1 байт.

bigint

Да

Использует минимально необходимое число байт. Например, если значение может храниться в 1 байте, то для его хранения будет использоваться всего 1 байт.

decimal

Да

Тот же тип хранения, что и для формата vardecimal. Дополнительные сведения см. в разделе Хранение десятичных данных в виде значений переменной длины.

numeric

Да

Тот же тип хранения, что и для формата vardecimal. Дополнительные сведения см. в разделе Хранение десятичных данных в виде значений переменной длины.

bit

Да

Издержки на метаданные приводят это значение к 4 битам.

smallmoney

Да

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

money

Да

Использует целочисленное представление данных с помощью 8-битового целого числа. Значение валюты умножается на 10000, а полученное целочисленное значение сохраняется с удалением всех нолей после десятичной запятой. Данный тип имеет больший диапазон, чем smallmoney. При хранении этого типа выполняется такая же оптимизация, что и для целочисленных типов.

float

Да

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

real

Да

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

smalldatetime

Нет

Использует целочисленное представление данных с использованием двухбайтных значений. Дата занимает 2 байта. Время представляет собой количество дней, прошедших с 01.01.1901. Начиная с 1902 г. необходимо 2 байта. Поэтому начиная с этой даты сэкономить место нельзя.

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

Если тип данных smalldatetime используется только для представления даты (обычно), время равно 0,0. При сжатии экономится 2 байта с помощью хранения времени в наиболее значимом байтовом формате для сжатия строки.

datetime

Да

Использует целочисленное представление данных с использованием двухбайтных значений. Целочисленное значение представляет количество дней, прошедших с 01.01.1900. Первые 2 байта могут представлять даты до 2079 г. Сжатие может сэкономить 2 байта до этой даты. Каждое целочисленное значение представляет собой 3,33 миллисекунды. Сжатие исчерпывает первые 2 байта в первые пять минут после 4:00, и становится необходимо четыре байта. Таким образом, сжатие может сэкономить только 1 байт после 4:00. Если тип данных datetime сжат, как другие целые числа, сжатие экономит 2 байта в дате.

date

Нет

Использует целочисленное представление данных с использованием трехбайтных значений. Это представляет дату начиная с 01.01.0001. Для современных дат сжатие строк использует все 3 байта. При этом экономии не получается.

time

Нет

Использует целочисленное представление данных длиной от 3 до 6 байт. Имеются различные степени точности, от 0 до 9, которые могут использовать от 3 до 6 байтов. Сжатое место используется следующим образом.

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

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

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

  • Точность = 3. Байты = 4. Поскольку до 05:00 берутся первые 3 байта, возникает небольшая экономия.

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

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

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

  • Точность = 8, байты = 6. Шестой байт будет использован после 03:00.

Хранение сжатой строки происходит без изменений. В целом при сжатии типа данных time может ожидаться небольшая экономия.

datetime2

Да

Использует целочисленное представление данных длиной от 6 до 9 байт. Первые 4 байта представляют дату. Количество байтов, берущихся для времени, будет зависеть от указанной точности времени.

Это целочисленное значение обозначает количество дней, прошедших с 01.01.0001, и ограничено верхней границей 31.12.9999. При представлении даты в 2005 г. сжатие экономит 3 байта.

Экономии при хранении времени не получается, так как оно занимает от 2 до 4 байт в зависимости от точности. Таким образом, при точности в одну секунду сжатие использует для времени 2 байта, начиная использовать второй байт после 255 секунд.

datetimeoffset

Да

Напоминает тип данных datetime2, за исключением того, что использует 2 байта часового пояса в формате (HH:MM).

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

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

Изменений в хранении сжатой строки нет.

char

Да

Конечные символы заполнения удаляются. Обратите внимание, что компонент Database Engine вставляет один и тот же символ заполнения, независимо от используемых параметров сортировки.

varchar

Нет

Не влияет.

text

Нет

Не влияет.

nchar

Да

Текст сжимается при помощи алгоритма стандартной схемы сжатия Юникода (SCSU), если размер сжатого текста не превышает размера самого текста.

nvarchar

Да

Текст сжимается при помощи алгоритма стандартной схемы сжатия Юникода (SCSU), если размер сжатого текста не превышает размера самого текста.

ПримечаниеПримечание
Сжатие не поддерживается для типа nvarchar(max).

ntext

Нет

Не влияет.

binary

Да

Замыкающие нули удаляются.

varbinary

Нет

Не влияет.

image

Нет

Не влияет.

cursor

Нет

Не влияет.

timestamp / rowversion

Да

Использует целочисленное представление данных с использованием трехбайтных значений. Значение счетчика отметок времени поддерживается для каждой базы данных, и это значение начинается с 0. Сжатие возможно и с другими целыми значениями.

sql_variant

Нет

Не влияет.

uniqueidentifier

Нет

Не влияет.

table

Нет

Не влияет.

xml

Нет

Не влияет.

Определяемые пользователем типы

Нет

Имеет внутреннее представление varbinary.

FILESTREAM

Нет

Имеет внутреннее представление varbinary.