Apakah SQL Server menggunakan pointer daripada menyimpan duplikat baris?
Itu tergantung pada versi SQL Server dan opsi kompresi data:
- Mulai dari SQL Server 2008, ada opsi kompresi di tingkat baris atau halaman.
- Kompresi tingkat halaman menggunakan banyak algoritma / teknik untuk kompresi. Mengenai pertanyaan Anda (petunjuk untuk data duplikat), kompresi halaman menggunakan (juga) kompresi awalan dan kompresi kamus :
Kompresi Awalan [...] Nilai awalan berulang dalam kolom digantikan oleh referensi ke awalan yang sesuai [...]
Kompresi Kamus Setelah kompresi awalan selesai, kompresi kamus diterapkan. Kompresi kamus mencari nilai berulang di mana saja pada halaman, dan menyimpannya di area CI. Tidak seperti kompresi awalan, kompresi kamus tidak terbatas pada satu kolom. Kompresi kamus dapat menggantikan nilai berulang yang terjadi di mana saja pada halaman. Ilustrasi berikut menunjukkan halaman yang sama setelah kompresi kamus.
Jadi, untuk awalan dan kompresi kamus (kompresi halaman), SQL Server menggunakan pointer untuk menyimpan (sebagian atau seluruhnya) nilai duplikat (bukan baris duplikat) dalam kolom yang sama atau di dalam diff. kolom.
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
Hasil:
PageCount_Person1_Uncompressed
------------------------------
53
PageCount_Person2_Compressed
----------------------------
2