資料壓縮

適用於:SQL ServerAzure SQL DatabaseAzure SQL 受控執行個體Microsoft Fabric 中的 SQL 資料庫

SQL Server、Azure SQL Database 和 Azure SQL 受控執行個體支援資料列和頁面壓縮 (針對資料列存放區的資料表和索引),亦支援資料行存放區和資料行存放區封存壓縮 (針對資料行存放區的資料表和索引)。

對於列存放資料表和索引,可使用資料壓縮功能來協助減少資料庫大小。 除了節省空間之外,資料壓縮也有助於改善 I/O 密集型工作負載的效能,因為資料會儲存在更少的頁面中,而且查詢需要從磁碟讀取的頁面也變少了。 但是在與應用程式交換資料時,資料庫伺服器上需要額外的 CPU 資源來壓縮和解壓縮資料。 您可以針對下列資料庫物件來設定資料列和頁面壓縮:

  • 以堆方式儲存的整個資料表。
  • 儲存為叢集索引的整個資料表。
  • 整個非叢集索引。
  • 完整的索引檢視。
  • 如果是分割資料表和索引,您可以針對每個資料分割設定壓縮選項,而物件的不同資料分割則不必擁有相同的壓縮設定。

對於資料行存放區資料表和索引,所有資料行存放區資料表和索引一律使用資料行存放區壓縮,且使用者無法加以設定。 當您可負擔額外的時間和 CPU 資源來儲存及擷取資料時,使用資料行存放區封存壓縮會進一步減少資料大小。 您可以針對下列資料庫物件來設定資料行存放區封存壓縮:

  • 整個資料行存放區資料表或整個叢集資料行存放區索引。 因為資料行存放區資料表會儲存成叢集資料行存放區索引,所以兩種方法有相同的結果。
  • 完整的非叢集資料行存放區索引。
  • 如果是分割資料行存放區資料表和資料行存放區索引,您可以針對每個資料分割設定封存壓縮選項,而不同資料分割則不必擁有相同的封存壓縮設定。

注意

資料也可以使用 GZIP 演算法格式進行壓縮。 這是額外的步驟,最適合在封存舊資料進行長期儲存時壓縮部分資料。 使用 COMPRESS 函式壓縮的資料無法編製索引。 如需詳細資訊,請參閱 COMPRESS (Transact-SQL)

資料列與頁面壓縮考量

當您使用資料列和頁面壓縮時,請注意以下考量事項:

  • Service Pack 或後續版本中的資料壓縮詳細資料可能會變更,恕不另行通知。

  • 可在 Azure SQL 資料庫中進行壓縮

  • 每一個 SQL Server 版本中都無法使用壓縮。 如需詳細資訊,請參閱本節結尾的版本和支援的功能清單。

  • 壓縮不適用於系統資料表。

  • 壓縮可讓更多的資料列儲存在頁面上,但是不會變更資料表或索引的資料列大小上限。

  • 當資料列大小上限加上壓縮額外負荷超過 8,060 位元組的資料列大小上限時,資料表無法啟用壓縮。 例如,由於額外壓縮負荷的緣故,所以具有資料行 c1 CHAR(8000)c2 CHAR(53) 的資料表無法加以壓縮。 當使用 vardecimal 儲存格式時,將會在啟用此格式時執行資料列大小檢查。 對於資料列和頁面壓縮而言,最初壓縮物件時會執行資料列大小檢查,然後在插入或修改每一個資料列時加以檢查。 壓縮會強制執行下列兩個規則:

    • 對固定長度類型的更新必須一律成功。
    • 停用資料壓縮一定要成功。 即使壓縮的資料列適合頁面大小,這表示它小於 8060 個位元組;如果它未壓縮,SQL Server 會防止不適合資料列大小的更新。
  • 啟用資料壓縮時,不會壓縮非資料列資料。 例如,如果 XML 記錄大於 8,060 位元組,就會使用資料列外頁面,而這些頁面不會經過壓縮。

  • 有幾種資料類型不受資料壓縮的影響。 如需詳細資訊,請參閱資料列壓縮如何影響儲存體

  • 當指定了資料分割清單時,壓縮類型可以在個別資料分割上設定為 ROWPAGENONE。 如果未指定分割區清單,則所有分割區都會套用陳述式中指定的資料壓縮屬性。 在建立資料表或索引時,除非另外指定,否則資料壓縮會設定為 NONE。 在修改資料表時,除非另外指定,否則會保留現有的壓縮。

  • 如果您指定分割區清單,或指定超出範圍的分割區,則會產生錯誤。

  • 非叢集索引不會繼承資料表的壓縮屬性。 若要壓縮索引,您必須明確設定索引的壓縮屬性。 根據預設,當建立索引時,索引的壓縮設定會設定為 NONE。

  • 在堆積上建立叢集索引時,此叢集索引會繼承堆積的壓縮狀態,除非指定了替代的壓縮狀態。

  • 當堆積已設定為頁面層級壓縮時,頁面只會以下列方式套用頁面層級壓縮:

    • 資料會在啟用大量最佳化的情況下大量匯入。
    • 使用 INSERT INTO ... WITH (TABLOCK) 語法來插入資料,此資料表沒有非叢集索引。
    • 執行 ALTER TABLE ... REBUILD 陳述式並指定 PAGE 壓縮選項來重建資料表。
  • 在重建堆積之前,作為 DML 作業一部分而在堆積中配置的新頁面不會使用 PAGE 壓縮。 您可以透過移除並重新套用壓縮,或建立並移除叢集索引,重建堆積。

  • 變更堆積的壓縮設定需要重建資料表上的所有非叢集索引,好讓它們擁有指向堆積內新資料列位置的指標。

  • 您可以在線上或離線時啟用或停用 ROWPAGE 壓縮。 在線上作業中,對堆啟用壓縮是以單一執行緒執行的。

  • 啟用或停用資料列或頁面壓縮的磁碟空間需求與建立或重建索引的需求相同。 對於分割區資料,您可以一次針對一個分割區啟用或停用壓縮,以減少所需空間。

  • 若要確定分割資料表中各資料分割的壓縮狀態,請查詢 sys.partitions 目錄檢視的 data_compression 資料行。

  • 當您壓縮索引時,葉節點層級頁面可以同時使用資料列壓縮和頁面壓縮。 非分葉層級頁面不會收到頁面壓縮。

  • 由於大數值資料類型的大小之緣故,這些類型有時會單獨儲存在特殊用途的頁面上,與一般資料列的資料分開。 資料壓縮不適用於個別儲存的資料。

  • 在 SQL Server 2005 (9.x) 中實作 Vardecimal 儲存格式的資料表會在升級時保留此設定。 您可以將資料列壓縮套用到具有 Vardecimal 儲存格式的資料表。 但是,由於資料列壓縮是 Vardecimal 儲存格式的超集,所以沒有理由保留 Vardecimal 儲存格式。 當您將 Vardecimal 儲存格式結合資料列壓縮時,十進位值不會取得額外的壓縮。 您可以對具有 vardecimal 儲存格式的資料表套用頁面壓縮;不過,vardecimal 儲存格式的資料行可能無法再達到進一步的壓縮效果。

    注意

    所有 SQL Server 支援版本都支援 Vardecimal 儲存格式;但是,由於資料壓縮會達成相同的目標,所以 Vardecimal 儲存格式已遭到取代。 SQL Server 的未來版本將移除此功能。 請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。

如需 SQL Server 在 Windows 上各版本所支援的功能清單,請參閱:

資料行存放區和資料行存放區封存壓縮

資料行存放區資料表和索引一律以資料行存放區壓縮格式儲存。 您可以進一步減少資料行存放區資料的大小,只要設定稱為封存壓縮的額外壓縮即可。 為了執行封存壓縮,SQL Server 會針對資料執行 Microsoft XPRESS 壓縮演算法。 您可以使用下列資料壓縮類型來新增或移除封存壓縮:

  • 使用 COLUMNSTORE_ARCHIVE 資料壓縮,以封存壓縮來壓縮資料行存放區的資料。
  • 使用 COLUMNSTORE 資料壓縮,將封存壓縮解壓縮。 產生的資料會持續以資料行存放區壓縮形式壓縮。

若要加入壓縮壓縮,請使用 ALTER TABLE (Transact-SQL)ALTER INDEX (Transact-SQL )並搭配 REBUILD 選項與 DATA COMPRESSION = COLUMNSTORE_ARCHIVE

例如:

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = 1 WITH (
    DATA_COMPRESSION = COLUMNSTORE_ARCHIVE
);

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = ALL WITH (
    DATA_COMPRESSION = COLUMNSTORE_ARCHIVE
);

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = ALL WITH (
    DATA_COMPRESSION = COLUMNSTORE_ARCHIVE ON PARTITIONS (2, 4)
);

若要移除歸檔壓縮並將資料恢復為欄位儲存壓縮,請使用 ALTER TABLE (Transact-SQL)ALTER INDEX (Transact-SQL) 並搭配 REBUILD 選項 和 DATA COMPRESSION = COLUMNSTORE

例如:

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = 1 WITH (
     DATA_COMPRESSION = COLUMNSTORE
);

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = ALL WITH (
    DATA_COMPRESSION = COLUMNSTORE
);

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = ALL WITH (
    DATA_COMPRESSION = COLUMNSTORE ON PARTITIONS (2, 4)
);

下一個範例會在某些資料分割上將資料壓縮設定為資料行存放區,以及在其他資料分割上設定為資料行存放區封存。

ALTER TABLE ColumnstoreTable1
REBUILD PARTITION = ALL WITH (
    DATA_COMPRESSION = COLUMNSTORE
        ON PARTITIONS (4, 5),
    DATA COMPRESSION = COLUMNSTORE_ARCHIVE
        ON PARTITIONS (1, 2, 3)
);

效能

以封存壓縮來壓縮資料行存放區索引時,會造成該索引的效能比沒有封存壓縮的資料行存放區索引還要慢。 只有當您可以負擔使用額外時間和 CPU 資源來壓縮及擷取資料時,才使用封存壓縮。

封存壓縮的好處就是減少儲存體,這對於不常存取的資料很實用。 例如,如果每個月份的資料各有一個分割區,而且大部分的活動都集中在最近幾個月,您可以將較舊月份的資料封存,以降低儲存需求。

中繼資料

下列系統檢視表包含叢集索引之資料壓縮的相關資訊:

sp_estimate_data_compression_savings (Transact-SQL) 程序也適用於資料行存放區索引。

分割資料表和索引的影響

當您搭配分割資料表和索引使用資料壓縮時,請注意以下考量事項:

  • 當使用 ALTER PARTITION 陳述式分割這些分割區時,兩個分割區都會繼承原始分割區的資料壓縮屬性。

  • 當合併兩個資料分割時,所產生的資料分割會繼承目標資料分割的資料壓縮屬性。

  • 若要切換資料分割,此資料分割的資料壓縮屬性必須符合資料表的壓縮屬性。

  • 您可以使用兩種語法變化來修改分割資料表或索引的壓縮:

    • 下列語法只會重建所參考的分割區:

      ALTER TABLE <table_name>
      REBUILD PARTITION = 1 WITH (
          DATA_COMPRESSION = <option>
      );
      
    • 下列語法會重建整個資料表,並對任何未被參照的資料分割區使用現有的壓縮設定:

      ALTER TABLE <table_name>
      REBUILD PARTITION = ALL WITH (
          DATA_COMPRESSION = PAGE ON PARTITIONS(<range>),
          ...
      );
      

    分割索引使用 ALTER INDEX 時,也遵循相同的原則。

  • 當卸除叢集索引時,除非修改了資料分割配置,否則對應的堆積資料分割會保留其資料壓縮設定。 如果資料分割配置有所變更,所有資料分割都會重建為未壓縮的狀態。 若要卸除叢集索引及變更資料分割配置,您需要執行以下步驟:

    1. 卸除叢集索引。
    2. 使用指定壓縮選項的 ALTER TABLE ... REBUILD 選項來修改資料表。

    卸除叢集索引 OFFLINE 是一項快速操作,因為只會移除叢集索引的上層。 卸除叢集索引 ONLINE 時,SQL Server 必須重建堆積兩次,一次在步驟 1,另一次在步驟 2。

壓縮將如何影響複寫

當您搭配複寫使用資料壓縮時,請注意以下考量事項:

  • 當快照集代理程式產生最初的結構描述指令碼時,新的結構描述會將相同的壓縮設定用於資料表和它的索引。 不能只在資料表上啟用壓縮,而不在索引上啟用壓縮。

  • 對於異動複寫,發行集結構描述選項會決定哪些相依物件和屬性必須編寫成指令碼。 如需詳細資訊,請參閱 sp_addarticle

    散發代理程式在套用指令碼時,不會檢查是否有下層的訂閱者。 如果選取了壓縮的複寫,在下層訂閱者上建立資料表就會失敗。 若為混合式拓撲,請勿啟用壓縮複寫。

  • 對於合併式複寫,發行集相容性層級會覆寫結構描述選項,並決定要編寫成指令碼的結構描述物件。

    對於混合式拓撲,如果不需要支援新的壓縮選項,則發行相容性層級應設定為較低版本的訂閱者版本。 如果需要,請在資料表建立之後於訂閱者端壓縮資料表。

下表顯示控制複寫期間壓縮的複寫設定。

使用者意圖 複製資料表或索引的資料分割配置 複寫壓縮設定 指令碼行為
複製分割配置,並在訂閱者端對該分割啟用壓縮。 為分割配置和壓縮設定編寫指令碼。
在訂閱者端複寫分割配置,但不壓縮資料。 會將資料分割配置編寫成指令碼,但不會將該資料分割的壓縮設定編寫成指令碼。
不複製分割配置,也不壓縮訂閱者端的資料。 不會為分割區或壓縮設定編寫指令碼。
如果發行者上的所有分割區都已壓縮,則壓縮訂閱者上的資料表,但不複寫分割配置。 檢查所有資料分割是否啟用壓縮。

針對資料表層級上的壓縮編寫指令碼。

對其他 SQL Server 元件造成的影響

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體

壓縮會發生在資料庫引擎中,而且資料會以非壓縮狀態呈現給 SQL Server 中的大多數其他元件。 這樣會將壓縮對其他元件的影響限制為以下因素:

  • 批次匯入及匯出作業
    • 當匯出資料時 (即使是原生格式),資料為非壓縮資料列格式的輸出。 這可能會造成匯出的資料檔大小比來源資料大出許多。
    • 當匯入資料時,如果目標資料表已啟用壓縮,則資料庫引擎會將資料轉換成壓縮的資料列格式。 這樣可能會造成 CPU 使用量增加 (相較於資料匯入未壓縮的資料表時)。
    • 將資料大量匯入具有頁面壓縮的堆積內時,大量匯入作業會在插入具有頁面壓縮的資料時,嘗試壓縮這些資料。
  • 壓縮不會影響備份和還原。
  • 壓縮不會影響記錄傳送。
  • 資料壓縮與稀疏資料行不相容。 因此,包含疏鬆資料行的資料表無法加以壓縮,也無法將疏鬆資料行加入至壓縮的資料表。
  • 啟用壓縮可能會造成查詢計畫變更,因為系統會使用不同的頁數以及每頁不同的資料列數來儲存資料。