SQL Server 效能瓶頸多半在於磁碟 I/O。資料壓縮透過減少磁碟佔用空間,間接提升 I/O 吞吐量、縮短備份/還原時間、降低儲存成本。SQL Server 2008 引入原生資料壓縮功能,支援列級壓縮與頁級壓縮兩種層級,可套用於資料表、叢集索引、非叢集索引、索引檢視、分割資料表與分割索引。
| 層級 | 包含關係 | 適用物件 | 建立/變更語法 |
|---|---|---|---|
| 列級壓縮 (ROW) | 基礎層級 | Table、Clustered Index、Nonclustered Index、Indexed View、Partitioned Table/Index | CREATE TABLE ... WITH (DATA_COMPRESSION = ROW|PAGE)ALTER TABLE ... REBUILD WITH (DATA_COMPRESSION = ROW|PAGE)ALTER INDEX ... REBUILD WITH (DATA_COMPRESSION = ROW|PAGE) |
| 頁級壓縮 (PAGE) | 包含列級壓縮 + 前綴壓縮 + 字典壓縮 |
注意:當堆疊資料表的壓縮狀態變更時,所有非叢集索引會自動重建。
列級壓縮著眼於「儲存格式最佳化」,不改變資料邏輯:
int、decimal、float 及衍生型別 (datetime、money) 依實際值大小動態調整位元組數。100 存入 int 原佔 4 bytes,壓縮後僅需 1 byte (0–255 範圍),省 3 bytes。char/nchar 視實際內容長度儲存,尾端空白不再佔空間。CHAR(10) 存 'CSDN',原佔 10 bytes,壓縮後僅 4 bytes。NULL 與 0 不再佔用任何位元組。頁級壓縮在列級基礎上,針對「單一資料頁內的重複值」進行跨列最佳化:
USE tempdb;
GO
-- 1. 建立測試表
CREATE TABLE TestCompression (
col1 INT,
col2 CHAR(50)
);
GO
-- 2. 灌入 5,000 筆測試資料
INSERT INTO TestCompression VALUES (10, 'compression testing');
GO 5000
-- 3. 查詢原始空間使用
EXEC sp_spaceused TestCompression;
GO
-- 4. 套用列級壓縮
ALTER TABLE TestCompression REBUILD WITH (DATA_COMPRESSION = ROW);
GO
EXEC sp_spaceused TestCompression;
GO
-- 5. 套用頁級壓縮
ALTER TABLE TestCompression REBUILD WITH (DATA_COMPRESSION = PAGE);
GO
EXEC sp_spaceused TestCompression;
GO
-- 6. 移除壓縮還原
ALTER TABLE TestCompression REBUILD WITH (DATA_COMPRESSION = NONE);
GO
EXEC sp_spaceused TestCompression;
GO
| 面向 | 列級壓縮 | 頁級壓縮 |
|---|---|---|
| CPU 開銷 | 低 | 中高(字典建立與查找) |
| 壓縮率 | 中等 (20–40%) | 高 (40–70%,視資料重複度) |
| 查詢效能 | 讀取受益大,CPU 幾無影響 | 讀取受益最大,但 CPU 額外負擔需評估 |
| 適用場景 | OLTP 高交易系統、數值/固定長字串欄位多 | 資料倉儲、唯讀/少寫入、高重複度欄位 (如維度表) |
sp_estimate_data_compression_savings 預估空間節省與 CPU 影響。SQL Server 2008 的資料壓縮是「以 CPU 換 I/O」的經典權衡。列級壓縮幾乎零負擔、適用面廣;頁級壓縮威力強大但需評估 CPU 容量。善用 sp_estimate_data_compression_savings 與實際負載測試,找出最適合系統的壓縮策略,能在不擴充硬體前提下大幅提升儲存效率與查詢效能。