Cai*_*haw 10 sql-server compression sql-server-2016
这是我昨天提出的一个问题的后续问题:我可以批量插入空的页面压缩表并获得完全压缩吗?这个问题的答案(转述自 Randi Vertongen 的优秀回答)是肯定的,但它要求批量插入采用表级锁;否则,大容量插入采用行级锁并仅执行行数据压缩。这就提出了一个问题:之后我如何知道应用了什么压缩?
下面是在理论上页压缩的表中创建行压缩数据的步骤:
1. 创建一个表,DATA_COMPRESSION=PAGE并不使用sp_tableoption打开该表的“批量加载表锁定”选项。
2. 使用 bcp 将平面文件中的数据批量插入到新表中,但不指定-h TABLOCK锁定表的选项。
结果是一个表中的数据在行级别上被压缩(小于未压缩表但大于页压缩表),但检查sys.allocation_units目录表显示数据压缩为页。
问题
在这种情况下,当表的数据分配用于页面压缩时,我该怎么做才能确定该表中的数据是否经过页面压缩?
Sol*_*zky 15
要查看数据页当前是否确实被“PAGE”压缩,您可以使用未记录的 DMF sys.dm_db_database_page_allocations()。该is_page_compressed字段包含您要查找的信息。您将需要使用DETAILED模式(即第 5 个参数),否则该字段中的值都将是NULL.
要清楚(基于问题的措辞,“我该怎么做才能确定该表中的数据是否经过页面压缩?”),这不是一个全有或全无的问题:应用了页面压缩每个数据页,因此您可以没有压缩,全部被压缩,或两者之间的任何组合。因此,您需要查看所有页面。不,您不能一定假设单个非页面压缩页面表明您需要,REBUILD因为未填充页面不会压缩。
例如:
SELECT [is_page_compressed]
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
0, 1, 'DETAILED');
Run Code Online (Sandbox Code Playgroud)
下图显示了数据页最初不是页压缩的,而是REBUILD操作后的:
USE [tempdb];
-- DROP TABLE dbo.CompressedHeap;
CREATE TABLE dbo.CompressedHeap
(
ID INT IDENTITY(1, 1) NOT NULL,
String sysname,
[MaxLength] SMALLINT,
[Type] VARCHAR(5)
) WITH (DATA_COMPRESSION = PAGE);
INSERT INTO dbo.CompressedHeap ([String], [MaxLength], [Type])
SELECT col.[name], col.[max_length], obj.[type]
FROM master.sys.columns col
CROSS JOIN master.sys.objects obj;
SELECT [is_page_compressed], *
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
0, 1, 'DETAILED')
WHERE [is_iam_page] = 0
AND [is_allocated] = 1;
-- 394 pages
ALTER TABLE dbo.CompressedHeap REBUILD;
SELECT [is_page_compressed], *
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
0, 1, 'DETAILED')
WHERE [is_iam_page] = 0
AND [is_allocated] = 1;
-- 179 pages
Run Code Online (Sandbox Code Playgroud)