Sql-Server

如何查看 SQL Server 表中的數據是否經過頁面壓縮?

  • August 13, 2019

這是我昨天提出的一個問題的後續問題:我可以批量插入一個空的頁面壓縮表並獲得完全壓縮嗎?該問題的答案(從 Randi Vertongen 的出色答案中轉述)是肯定的,但它要求批量插入採用表級鎖定;否則,批量插入將採用行級鎖定並僅執行行數據壓縮。這就提出了一個問題:我如何才能知道應用了什麼壓縮?

以下是在理論上頁壓縮表中創建行壓縮數據的步驟:

  1. 創建一個表,DATA_COMPRESSION=PAGEsp_tableoption為該表打開“批量載入表鎖定”選項。

  2. 使用 bcp 將平面文件中的數據批量插入到新表中,但不指定-h TABLOCK鎖定表的選項。

結果是一個數據在行級別壓縮的表(小於未壓縮表但大於頁壓縮表),但檢查sys.allocation_units目錄表會顯示數據壓縮為頁。

問題

在這種情況下,當表的數據分配用於頁面壓縮時,我該怎麼做才能確定該表中的數據是否經過頁面壓縮?

要查看數據頁目前是否確實被“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');

下圖顯示數據頁最初不是頁壓縮的,而是經過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

引用自:https://dba.stackexchange.com/questions/245254