Sql-Server
如何查看 SQL Server 表中的數據是否經過頁面壓縮?
這是我昨天提出的一個問題的後續問題:我可以批量插入一個空的頁面壓縮表並獲得完全壓縮嗎?該問題的答案(從 Randi Vertongen 的出色答案中轉述)是肯定的,但它要求批量插入採用表級鎖定;否則,批量插入將採用行級鎖定並僅執行行數據壓縮。這就提出了一個問題:我如何才能知道應用了什麼壓縮?
以下是在理論上頁壓縮表中創建行壓縮數據的步驟:
創建一個表,
DATA_COMPRESSION=PAGE
並sp_tableoption
為該表打開“批量載入表鎖定”選項。使用 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