從SQL SERVER 2008開始,SQL SERVER 提供了對數據進行壓縮的功能,啓用數據壓縮無須修改應用程序。算法
數據壓縮可有效減小數據的佔用空間,讀取和寫入相同數據花費的IO也響應減小,從而能夠有效緩解IO壓力,但因爲數據在讀取和寫入時須要壓縮和解壓縮,所以會消耗CPU資源,但不表明在相同負載下,啓用數據壓縮會致使CPU的使用率變高,某些操做會由於數據頁數量的減小而下降CPU資源的消耗。數據庫
能夠配置數據壓縮的對象有:
1>存儲爲堆的整個表。
2>存儲爲彙集索引的整個表。
3>整個非彙集索引。
4>整個索引視圖。
5>對於已分區表和已分區索引,可爲每一個分區配置壓縮選項,且對象的各個分區的壓縮設置沒必要相同。
(我的理解:數據壓縮是在parition級別上使用,未分區表和未分區索引一樣能夠找到一個對應的partitionID)ui
數據壓縮方式有兩種
1:行壓縮
2:頁壓縮編碼
行壓縮實現:
行壓縮更改與數據類型相關聯的數據的物理存儲格式來實現壓縮:
1>減小了與記錄相關聯的元數據開銷。 此元數據爲有關列、列長度和偏移量的信息。 在某些狀況下,元數據開銷可能大於舊的存儲格式。
2>它對於數值類型(例如,integer、decimal 和 float)和基於數值的類型(例如,datetime 和 money)使用可變長度存儲格式。
3>它經過使用不存儲空字符的可變長度格式來存儲定長字符串。spa
快速理解:
對應數值類型和基於數值的類型來講,因爲須要類型定義範圍內的數據,所以須要相對較大的定長空間,如BIGINT佔用8個字節,但對於值1來講,只須要一個字節即可以存放,啓用行壓縮即可以節省7個字節的空間;對於定長數據類型,若是存放的數據未達到指定長度,會補空字符來填滿,如類型CHAR(200)用來存放字符串"1"會花費200個字節,但啓用行壓縮後,會將填充的空字符移除,只須要1個字節即可以存放。而對於類型bit來講,除自身消耗的空間外,還須要額外的4個bit來存放元數據,所以也能夠從行壓縮中獲益。code
行壓縮影響的數據類型可參考http://msdn.microsoft.com/zh-cn/library/cc280576.aspxserver
頁壓縮實現:
頁壓縮是在行壓縮的基礎上進行前綴壓縮,而後再進行字典壓縮對象
前綴壓縮:前綴壓縮針對頁中的各列來進行壓縮,首先從列中選取出一個前綴值(不要求頁中每一行的該列的值都包含此前綴)存放在頁頭,而後使用該前綴替換頁中每一行的該列值,如提起前綴爲aabbcc,對應值aabbccdd則替換爲6dd,對應值aadd則替換爲2dd,對應值ccbbdd則替換成0ccbbdd,對應值aabbcc則替換成[],每行會生成一個前綴來處理。blog
字典壓縮:字典壓縮是在前綴壓縮完成後,搜索頁面上任意位置的重複值,而後將它們存儲在 CI 區域中。 與前綴壓縮不一樣,字典壓縮不侷限於一列。 字典壓縮能夠替換頁面上任意位置出現的重複值。索引
當表和索引使用頁壓縮後,對於一個新的頁面,插入數據行時會對該行啓用行壓縮,直到該頁已滿沒法存放新增長的行時,纔會使用頁壓縮的算法計算啓用頁壓縮是否能存放新增長的行,若是能夠存放,則對該頁進行頁壓縮並將新增長的行放到該頁,若是不能存放,則不對該頁啓用頁壓縮,申請新頁來存放新行。
在SQL SERVER 2012中,SQL Server 使用 Unicode 標準壓縮方案 (Standard Compression Scheme for Unicode, SCSU) 算法實現來壓縮在行或頁壓縮對象中存儲的 Unicode 值。 對於這些壓縮對象,Unicode 壓縮對於 nchar(n) 和 nvarchar(n) 列而言是自動的。 數據庫引擎 將 Unicode 數據存儲爲 2 個字節,不管區域設置如何。 這稱爲 UCS-2 編碼。 對於某些區域設置而言,在 SQL Server 中實現 SCSU 壓縮可節省高達 50% 的存儲空間。
數據壓縮Demo
--============================================================================================================================= --========================================================= --判斷表和索引是否啓用壓縮和壓縮類型 --宋桑提供 SELECT DISTINCT SCHEMA_NAME(o.schema_id) + '.' + OBJECT_NAME(o.object_id) AS TableName, i.name AS IndexName, p.data_compression_desc AS CompressionType, i.type_desc AS StorageType FROM sys.partitions p with(nolock) INNER JOIN sys.objects o with(nolock) ON p.object_id = o.object_id JOIN sys.indexes i ON p.object_id = i.object_id AND i.index_id = p.index_id WHERE p.data_compression > 0 AND SCHEMA_NAME(o.schema_id) <> 'SYS' --========================================================= --使用採樣來預估數據對象啓用壓縮先後的空間使用 --參考連接:http://msdn.microsoft.com/zh-cn/library/cc280574.aspx --PS:該算法只能起參考做用,數據壓縮獲得的空間可能比預估的要大不少 EXEC sp_estimate_data_compression_savings 'dbo', 'TB', NULL, NULL, 'ROW' ; --========================================================= --對錶使用數據壓縮 ALTER TABLE <table_name> REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE|ROW) --========================================================= --對錶中特定分區指定壓縮 ALTER TABLE <table_name> REBUILD PARTITION = 1 WITH (DATA_COMPRESSION = PAGE|ROW) --========================================================= --對錶中多個特定分區指定壓縮 ALTER TABLE <table_name> REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE ON PARTITIONS(<range>), ... ) --========================================================= --在新建索引時指定壓縮 CREATE CLUSTERED INDEX [CLX_ID] ON [dbo].[TB2] ( [ID] ASC )WITH (DATA_COMPRESSION = { NONE | ROW | PAGE}) ON [PRIMARY] GO --========================================================= --使用重建索引來進行壓縮 ALTER INDEX [CLX_ID] ON [dbo].[TB2] REBUILD PARTITION = ALL WITH ( DATA_COMPRESSION = { NONE | ROW | PAGE }) --=============================================================================================================================
壓縮試驗:
壓縮表定義爲:
CREATE TABLE [dbo].[TB1]( [id] [bigint] IDENTITY(1,1) PRIMARY KEY, [star_uid] [bigint] NOT NULL, [source_uid] [bigint] NOT NULL, [site_type] [tinyint] NOT NULL, [site_server_type] [tinyint] NOT NULL, [site_id] [bigint] NOT NULL, [count] [int] NOT NULL, [create_date] [bigint] NOT NULL, ) ON [PRIMARY]
壓縮前佔用空間:7309288KB
壓縮後佔用空間:2594624KB
壓縮使用時間:3分58秒
壓縮環境:8Core 32G 4塊SAS(15000轉4盤片)作RAID 10
--未完待續
參考連接:http://msdn.microsoft.com/zh-cn/library/cc280449.aspx
慣例上圖引狼