¿SQL Server utiliza punteros en lugar de almacenar filas duplicadas?
Depende de la versión de SQL Server y las opciones de compresión de datos:
- A partir de SQL Server 2008, hay una opción de compresión a nivel de fila o página.
- La compresión a nivel de página utiliza muchos algoritmos / técnicas para la compresión. Con respecto a su pregunta (punteros para datos duplicados), la compresión de página usa (también) compresión de prefijo y compresión de diccionario :
Compresión de prefijo [...] Los valores de prefijo repetidos en la columna se reemplazan por una referencia al prefijo correspondiente [...]
Compresión del diccionario Después de completar la compresión del prefijo, se aplica la compresión del diccionario. La compresión de diccionario busca valores repetidos en cualquier parte de la página y los almacena en el área de CI. A diferencia de la compresión de prefijos, la compresión de diccionario no está restringida a una columna. La compresión de diccionario puede reemplazar los valores repetidos que ocurren en cualquier lugar de una página. La siguiente ilustración muestra la misma página después de la compresión del diccionario.
Entonces, para la compresión de prefijos y diccionarios (compresión de páginas), SQL Server usa punteros para almacenar (duplicados total o parcialmente) valores duplicados (no filas duplicadas) dentro de la misma columna o dentro de diff. columnas
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
Resultados:
PageCount_Person1_Uncompressed
------------------------------
53
PageCount_Person2_Compressed
----------------------------
2