可以在独立表空间或通用表空间内创建压缩表。压缩表不适用于InnoDB系统表空间。系统表空间(space 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。要了解更多信息,请查阅15.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;
注意事项 #
从MySQL8.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)的变小,也不会将磁盘空间归还给操作系统。想了解更多信息,请查阅15.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设置。想了解更多信息,请查阅15.6.3.3,“通用表空间”。
InnoDB支持32KB和64KB大小的页,但是这两种规格的页不支持压缩。想了解更多信息,可以查询innodb_page_size相关文档。
未压缩的InnoDB数据页大小是16KB。对于表空间数据文件(.ibd文件),MySQL使用的页大小可能是1KB,2KB,4KB,8KB,或16KB,这取决于各种选项设置值。真实的压缩算法不会受KEY_BLOCK_SIZE大小的影响;这个值决定了每一个压缩区块大小,这反过来会影响每个压缩页可以容纳多少条记录。
当使用独立表空间创建压缩表时,将KEY_BLOCK_SIZE设置为何InnoDB的页大小相等通知不会产生多大压缩效果。例如,将KEY_BLOCK_SIZE设置为16通常不会产生多大压缩效果,因为正常的InnoDB页大小是16KB。这个设置可能对于有很多BLOB,VARCHAR或TEXT类型的列的表来说可能仍然有用,因为这些类型的列的值通常压缩效果不错,而且可以节省很多溢出页(见15.9.1.5,“InnoDB的表压缩原理”)。对于通用表空间,不允许将KEY_BLOCK_SIZE设置为何InnoDB的页带下相等。想了解更多信息,请查阅15.6.3.3,“通用表空间”。
一张表的所有索引(包括聚簇索引)都被按相同大小的页压缩,像CREATE TABLE或ALTER TABLE语句指定的那样。对于InnoDB表,表的属性(比如ROW_FORMAT和KEY_BLOCK_SIZE)不是CREATE INDEX语法的一部分,所以如果指定的话会被忽略(但是,如果指定的话,仍然会在SHOW CREATE TABLE语句的输出中展示)。
想了解性能相关的设置选项,请查阅15.9.1.3,“InnoDB压缩表调优”。
压缩表的限制 #
压缩表不可以存储在系统表空间中。
通用表空间可以包含多张表,但是压缩表和非压缩表不可以存在于同一个通用表空间中。
压缩只能用于整张表及其索引,不能用于部分记录,不管ROW_FORMAT是什么。
InnoDB不支持压缩临时表。当启用innodb_strict_mode时(默认启用),CREATE TEMPORARY TABLE时如果指定ROW_FORMAT=COMPRESSED或KEY_BLOCK_SIZE会返回错误。如果禁用innodb_strict_mode,会用非压缩格式创建临时表并产生警告。同样的限制也适用于对于临时表的ALTER TABLE操作。