压缩表可以在 每个表文件 表空间或 通用表空间 中创建。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.3 开始,对于压缩表,表空间文件的创建使用物理页大小,而不是
InnoDB
页大小,这使得空压缩表的表空间文件的初始大小小于以前的 MySQL 版本。 -
如果指定
ROW_FORMAT=COMPRESSED
,可以省略KEY_BLOCK_SIZE
;KEY_BLOCK_SIZE
设置默认为innodb_page_size
值的一半。 -
如果指定了有效的
KEY_BLOCK_SIZE
值,可以省略ROW_FORMAT=COMPRESSED
;压缩将自动启用。 -
要确定
KEY_BLOCK_SIZE
的最佳值,通常可以创建多个具有不同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
,不是CREATE INDEX
语法的一部分,对于InnoDB
表是忽略的(尽管,如果指定了它们,将出现在SHOW CREATE TABLE
语句的输出中)。 -
有关性能相关的配置选项,请参阅 第 17.9.1.3 节,“InnoDB 表的压缩调整”。
压缩表的限制
-
压缩表不能存储在
InnoDB
系统表空间中。 -
通用表空间可以包含多个表,但压缩和未压缩表不能在同一个通用表空间中共存。
-
压缩适用于整个表和所有相关索引,而不是单个行,尽管子句名称为
ROW_FORMAT
。 -
InnoDB
不支持压缩临时表。当innodb_strict_mode
启用(默认情况下),CREATE TEMPORARY TABLE
如果指定ROW_FORMAT=COMPRESSED
或KEY_BLOCK_SIZE
将返回错误。如果innodb_strict_mode
禁用,警告将被发出,并且临时表将使用非压缩行格式创建。相同的限制也适用于ALTER TABLE
操作临时表。