Использует ли SQL Server указатели вместо хранения повторяющихся строк?
Это зависит от версии SQL Server и параметров сжатия данных:
- Начиная с SQL Server 2008, существует опция сжатия на уровне строки или страницы.
- Сжатие на уровне страницы использует много алгоритмов / методов для сжатия. Что касается вашего вопроса (указатели для дублированных данных), сжатие страниц использует (также) префиксное сжатие и словарное сжатие :
Сжатие префикса [...] Повторяющиеся значения префикса в столбце заменяются ссылкой на соответствующий префикс [...]
Сжатие словаря После завершения префиксного сжатия применяется сжатие словаря. Сжатие по словарю ищет повторяющиеся значения в любом месте страницы и сохраняет их в области CI. В отличие от префиксного сжатия, словарное сжатие не ограничивается одним столбцом. Сжатие словаря может заменить повторяющиеся значения, которые встречаются в любом месте на странице. На следующем рисунке показана та же страница после сжатия словаря.
Таким образом, для сжатия префиксов и словарей (сжатие страниц) SQL Server использует указатели для хранения (частично или полностью) дублированных значений (не дублированных строк) в одном столбце или в diff. колонны.
CREATE DATABASE TestComp;
GO
USE TestComp;
GO
CREATE TABLE Person1 (
PersonID INT IDENTITY PRIMARY KEY,
FirstName NVARCHAR(100) NOT NULL,
LastName NVARCHAR(100) NOT NULL
);
GO
DECLARE
@f NVARCHAR(100) = REPLICATE('A',100),
@l NVARCHAR(100) = REPLICATE('B',100);
INSERT Person1 (FirstName, LastName)
VALUES (@f, @l);
GO 1000
CREATE TABLE Person2 (
PersonID INT IDENTITY PRIMARY KEY,
FirstName NVARCHAR(100) NOT NULL,
LastName NVARCHAR(100) NOT NULL
);
GO
ALTER TABLE Person2
REBUILD
WITH (DATA_COMPRESSION=PAGE);
GO
DECLARE
@f NVARCHAR(100) = REPLICATE('A',100),
@l NVARCHAR(100) = REPLICATE('B',100);
INSERT Person2 (FirstName, LastName)
VALUES (@f, @l);
GO 1000
SELECT f.page_count AS PageCount_Person1_Uncompressed
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('Person1'), 1, DEFAULT, DEFAULT) f
SELECT f.page_count AS PageCount_Person2_Compressed
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('Person2'), 1, DEFAULT, DEFAULT) f
GO
Результаты:
PageCount_Person1_Uncompressed
------------------------------
53
PageCount_Person2_Compressed
----------------------------
2