資料列壓縮實作

本主題摘要說明 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

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

nvarchar

沒有影響。

ntext

沒有影響。

binary

會移除尾端的零。

varbinary

沒有影響。

image

沒有影響。

cursor

沒有影響。

timestamp / rowversion

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

sql_variant

沒有影響。

uniqueidentifier

沒有影響。

table

沒有影響。

xml

沒有影響。

使用者定義型別

這在內部是表示為 varbinary。

FILESTREAM

這在內部是表示為 varbinary。