壓縮資料表可以在每個資料表檔案表空間或通用表空間中建立。資料表壓縮不適用於 InnoDB 系統表空間。系統表空間(空間 0,.ibdata 檔案)可以包含使用者建立的資料表,但它也包含內部系統資料,永遠不會壓縮。因此,壓縮僅適用於儲存在每個資料表檔案或通用表空間中的資料表(和索引)。
在每個資料表檔案表空間中建立壓縮資料表
若要在每個資料表檔案表空間中建立壓縮資料表,必須啟用innodb_file_per_table
(預設)。您可以使用 MySQL 組態檔 (my.cnf
或 my.ini
) 或使用 SET
陳述式動態設定此參數。
在設定innodb_file_per_table
選項後,在 CREATE TABLE
或 ALTER TABLE
陳述式中指定 ROW_FORMAT=COMPRESSED
子句或 KEY_BLOCK_SIZE
子句,或兩者皆指定,以在每個資料表檔案表空間中建立壓縮資料表。
例如,您可以使用下列陳述式
SET GLOBAL innodb_file_per_table=1;
CREATE TABLE t1
(c1 INT PRIMARY KEY)
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
在通用表空間中建立壓縮資料表
若要在通用表空間中建立壓縮資料表,必須為通用表空間定義 FILE_BLOCK_SIZE
,這是建立表空間時所指定的。FILE_BLOCK_SIZE
值必須是相對於 innodb_page_size
值的有效壓縮頁面大小,並且由 CREATE TABLE
或 ALTER TABLE
KEY_BLOCK_SIZE
子句定義的壓縮資料表頁面大小,必須等於 FILE_BLOCK_SIZE/1024
。例如,如果 innodb_page_size=16384
且 FILE_BLOCK_SIZE=8192
,則資料表的 KEY_BLOCK_SIZE
必須是 8。如需更多資訊,請參閱第 17.6.3.3 節,「通用表空間」。
以下範例示範建立通用表空間並新增壓縮資料表。此範例假設預設的 innodb_page_size
為 16K。FILE_BLOCK_SIZE
為 8192,表示壓縮資料表的 KEY_BLOCK_SIZE
必須為 8。
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB;
mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
注意事項
從 MySQL 8.4 開始,壓縮資料表的表空間檔案是使用實際頁面大小而非
InnoDB
頁面大小建立,這使得空白壓縮資料表的表空間檔案初始大小比先前 MySQL 版本小。如果您指定
ROW_FORMAT=COMPRESSED
,則可以省略KEY_BLOCK_SIZE
;KEY_BLOCK_SIZE
設定預設為innodb_page_size
值的一半。如果您指定有效的
KEY_BLOCK_SIZE
值,則可以省略ROW_FORMAT=COMPRESSED
;壓縮功能會自動啟用。要判斷
KEY_BLOCK_SIZE
的最佳值,通常您會建立多個具有不同此子句值的相同資料表副本,然後測量產生的.ibd
檔案大小,並查看每個副本在實際的工作負載下的效能。對於通用表空間,請記住,刪除資料表不會縮減通用表空間.ibd
檔案的大小,也不會將磁碟空間返回給作業系統。有關更多資訊,請參閱第 17.6.3.3 節「通用表空間」。KEY_BLOCK_SIZE
值被視為提示;如有必要,InnoDB
可以使用不同的大小。對於 file-per-table 表空間,KEY_BLOCK_SIZE
只能小於或等於innodb_page_size
的值。如果您指定的值大於innodb_page_size
的值,則會忽略指定的值,並發出警告,並且KEY_BLOCK_SIZE
會設定為innodb_page_size
值的一半。如果innodb_strict_mode=ON
,則指定無效的KEY_BLOCK_SIZE
值會傳回錯誤。對於通用表空間,有效的KEY_BLOCK_SIZE
值取決於表空間的FILE_BLOCK_SIZE
設定。有關更多資訊,請參閱第 17.6.3.3 節「通用表空間」。InnoDB
支援 32KB 和 64KB 的頁面大小,但這些頁面大小不支援壓縮。有關更多資訊,請參閱innodb_page_size
文件。InnoDB
資料頁面的預設未壓縮大小為 16KB。根據選項值的組合,MySQL 會將表空間資料檔案 (.ibd
檔案) 的頁面大小設為 1KB、2KB、4KB、8KB 或 16KB。KEY_BLOCK_SIZE
值不會影響實際的壓縮演算法;該值決定每個壓縮區塊的大小,這反過來又會影響每個壓縮頁面中可以封裝多少列。當在 file-per-table 表空間中建立壓縮資料表時,將
KEY_BLOCK_SIZE
設定為等於InnoDB
頁面大小 通常不會產生太多壓縮。例如,設定KEY_BLOCK_SIZE=16
通常不會產生太多壓縮,因為正常的InnoDB
頁面大小為 16KB。此設定對於具有許多長BLOB
、VARCHAR
或TEXT
資料行的資料表可能仍然有用,因為此類值通常壓縮效果良好,因此可能需要較少的溢位頁面,如第 17.9.1.5 節「InnoDB 資料表的壓縮原理」中所述。對於通用表空間,不允許KEY_BLOCK_SIZE
值等於InnoDB
頁面大小。有關更多資訊,請參閱第 17.6.3.3 節「通用表空間」。資料表的所有索引 (包括叢集索引) 都使用相同的頁面大小進行壓縮,如
CREATE TABLE
或ALTER TABLE
陳述式中所指定。資料表屬性 (例如ROW_FORMAT
和KEY_BLOCK_SIZE
) 不是InnoDB
資料表的CREATE INDEX
語法的一部分,如果指定了這些屬性,則會忽略它們 (儘管如果指定了這些屬性,它們會出現在SHOW CREATE TABLE
陳述式的輸出中)。有關效能相關的組態選項,請參閱第 17.9.1.3 節「調整 InnoDB 資料表的壓縮」。
壓縮資料表的限制
壓縮資料表無法儲存在
InnoDB
系統表空間中。通用表空間可以包含多個資料表,但壓縮和未壓縮的資料表無法在同一個通用表空間中共存。
壓縮適用於整個資料表及其所有相關索引,而不是個別的列,儘管子句名稱為
ROW_FORMAT
。InnoDB
不支援壓縮的暫存資料表。當啟用innodb_strict_mode
(預設值) 時,如果指定了ROW_FORMAT=COMPRESSED
或KEY_BLOCK_SIZE
,CREATE TEMPORARY TABLE
會傳回錯誤。如果停用了innodb_strict_mode
,則會發出警告,並使用未壓縮的列格式建立暫存資料表。相同的限制也適用於暫存資料表上的ALTER TABLE
操作。