压缩表可以在每个表一个文件 表空间或通用表空间 中创建。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 要求压缩表具有 8 的 KEY_BLOCK_SIZE
。
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 9.0 开始,压缩表的表空间文件使用物理页面大小而不是
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
可以使用不同的尺寸。对于每个表一个文件的表空间,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 使用 1KB、2KB、4KB、8KB 或 16KB 的页面大小来存储表空间数据文件 (.ibd
文件)。实际的压缩算法不受KEY_BLOCK_SIZE
值的影响;该值决定了每个压缩块的大小,进而影响了每个压缩页面中可以容纳多少行。在每个表一个文件的表空间中创建压缩表时,将
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
操作。