資料列壓縮實作

本主題摘要說明 Database Engine 如何實作資料列壓縮。這個摘要提供協助您計畫資料所需之儲存空間的基本資訊。

啟用壓縮僅會變更與資料類型 (但不與其語法或語意) 相關聯之資料的實體儲存格式。當啟用一或多個資料表的壓縮時,不需要變更應用程式。新的記錄儲存格式具有下列的主要變更:

  • 降低與記錄相關聯的中繼資料負擔。此中繼資料是有關資料行、其長度和位移的資訊。在某些情況下,中繼資料負擔可能會比舊的儲存格式還大。

  • 針對數值類型 (例如 integer、decimal 和 float) 以及依據數值的類型 (例如 datetime 和 money) 使用可變長度儲存格式。

  • 使用可變長度格式 (不儲存空白字元) 而儲存固定字元字串。

[!附註]

所有資料類型的 NULL 和 0 值都經過最佳化而不使用任何位元組。

資料列壓縮如何影響儲存

下表描述資料列壓縮如何影響 SQL Server 中的現有類型。此表格不包含可藉由使用頁面壓縮而達成的節省量。

資料類型

儲存是否受到影響?

描述

tinyint

所需的最小儲存區是 1 個位元組。

smallint

如果 1 個位元組能容納此值,只會使用 1 個位元組。

int

僅使用所需的位元組。例如,如果值可以儲存在 1 個位元組內,則儲存只會使用 1 個位元組。

bigint

僅使用所需的位元組。例如,如果值可以儲存在 1 個位元組內,則儲存只會使用 1 個位元組。

decimal

此儲存與 Vardecimal 儲存格式完全相同。如需詳細資訊,請參閱<將十進位資料儲存成可變長度>。

numeric

此儲存與 Vardecimal 儲存格式完全相同。如需詳細資訊,請參閱<將十進位資料儲存成可變長度>。

bit

中繼資料負荷將此設為 4 個位元。

smallmoney

藉由使用 4 位元組整數來使用整數資料表示。貨幣值會乘以 10000,再移除小數點之後的任何數字以儲存產生的整數值。此類型的儲存最佳化與整數類型類似。

money

藉由使用 8 位元組整數來使用整數資料表示。貨幣值會乘以 10000,再移除小數點之後的任何數字以儲存產生的整數值。此類型的範圍比 smallmoney 大。此類型的儲存最佳化與整數類型類似。

float

不會儲存具有零的最低有效位元。float 壓縮大多適用於尾數中的非小數值。

real

不會儲存具有零的最低有效位元。real 壓縮大多適用於尾數中的非小數值。

smalldatetime

藉由使用兩個 2 位元組整數來使用整數資料表示。日期會使用 2 個位元組,是 1901 年 1 月 1 日之後的日數。這需要 2 個位元組,從 1902 開始;因此在該時間點後就無法進行節省。

時間是午夜之後的分鐘數。稍微超過 4AM 的時間值會開始使用第二個位元組。

如果 smalldatetime 只會用來表示日期 (常見的情況),則時間是 0.0。壓縮會針對資料列壓縮以最大顯著性位元組格式儲存時間而節省 2 個位元組。

datetime

藉由使用兩個 4 位元組整數來使用整數資料表示。整數值代表日數,基底日期則是 1900 年 1 月 1 日。第一個 2 位元組最多可代表到 2079 年。在該時間點之前,此處的壓縮一定可以節省 2 個位元組。每個整數值都代表 3.33 毫秒。壓縮在第一個五分鐘內就會用盡第一個 2 個位元組,而需要在 4PM 之後使用第四個位元組。因此,在 4PM 之後僅能節省 1 個位元組。當 datetime 像任何其他整數一樣進行壓縮時,壓縮可以在日期中節省 2 個位元組。

date

藉由使用 3 個位元組來使用整數資料表示。這代表從 0001 年 1 月 1 日開始的日期。對於現代的日期而言,資料列壓縮會使用所有 3 個位元組。如此不會達成任何節省量。

time

藉由使用 3 到 6 個位元組來使用整數資料表示。有多個以 0 到 9 的有效位數可以使用 3 到 6 個位元組。壓縮空間的用法如下所示:

  • Precision = 0。Bytes = 3。每個整數值都代表一秒。壓縮可藉由使用 2 個位元組而最多代表到 6PM 的時間,因而可能節省 1 個位元組。

  • Precision = 1。Bytes = 3。每個整數值都代表 1/10 秒。壓縮在 2AM 之前會使用第三個位元組。產生的節省量很少。

  • Precision = 2。Bytes = 3。與前例類似,不太可能達到節省量。

  • Precision = 3。Bytes = 4。因為在 5AM 之前就會使用了第一個 3 位元組,所以節省的量很少。

  • Precision = 4。Bytes = 4。在第一個 27 秒內就會使用第一個 3 位元組。不預期有任何節省量。

  • Precision = 5,Bytes = 5。在中午 12 點之後會使用第五個位元組。

  • Precision = 6 和 7,Bytes = 5。不會達到任何節省量。

  • Precision = 8,Bytes = 6。在 3AM 之後會使用第六個位元組。

資料列壓縮的儲存沒有變更。整體而言,無法預期從壓縮 time 資料類型達到很大的節省量。

datetime2

藉由使用 6 到 9 個位元組來使用整數資料表示。第一個 4 位元組代表日期。由時間所使用的位元組會依所指定時間的有效位數而定。

整數值代表自 0001 年 1 月 1 日開始的日數,上限則是 9999 年 12 月 31 日。為了代表 2005 年中的日期,壓縮會使用 3 個位元組。

不會節省任何時間,因為它針對不同的時間有效位數而允許 2 到 4 個位元組。因此,對於一秒鐘的時間有效位數而言,壓縮會為時間使用 2 個位元組,而在 255 秒之後使用第二個位元組。

datetimeoffset

類似 datetime2,但此格式 (HH:MM) 的時區有 2 個位元組。

與 datetime2 類似,壓縮可節省 2 個位元組。

對於時區值,MM 值在多數情況下可能是 0。因此,壓縮可能可以節省 1 個位元組。

資料列壓縮的儲存沒有變更。

char

會移除尾端填補字元。請注意,不論使用的定序為何,Database Engine 都會插入相同的填補字元。

varchar

沒有影響。

text

沒有影響。

nchar

如果壓縮的文字大小小於目前的文字大小,就會使用 Standard Compression Scheme for Unicode (SCSU) 演算法來壓縮文字。

nvarchar

如果壓縮的文字大小小於目前的文字大小,就會使用 Standard Compression Scheme for Unicode (SCSU) 演算法來壓縮文字。

附註附註
壓縮不支援 nvarchar(max)。

ntext

沒有影響。

binary

會移除尾端的零。

varbinary

沒有影響。

image

沒有影響。

cursor

沒有影響。

timestamp / rowversion

藉由使用 8 個位元組來使用整數資料表示。有針對每個資料庫維護時間戳記計數器,且其值從 0 開始。這可以像任何其他整數值一般進行壓縮。

sql_variant

沒有影響。

uniqueidentifier

沒有影響。

table

沒有影響。

xml

沒有影響。

使用者定義型別

這在內部是表示為 varbinary。

FILESTREAM

這在內部是表示為 varbinary。