数据在磁盘上的表现是存在文件中,而文件格式决定了InnoDB的数据存储特性,随着InnoDB的发展,也逐渐出现效率更高的存储格式,目前InnoDB共支持两种文件格式:
- Antelope(羚羊),旧的文件存储格式,支持compact和redundant两种行存储格式。
- Barracuda(梭鱼),最新的文件存储格式,除了支持compact和redundant两种格式,还额外支持dynamic和compressed两种行存储格式。
InnoDB的文件存储格式由参数innodb_file_format控制,为了兼容性,其默认值为Antelope。
如果系统支持可以使用set global命令启用Barracuda文件存储格式,但是如果要使用dynamic和compressed行存储格式,还需要将innodb_file_per_table参数设置为on来启用独立表空间,因为这两种行格式的表无法存储在系统表空间。
当启用Barracuda文件存储格式时,仅会对以后创建的表生效。而且如果表未使用最新的dynamic或compressed格式时,InnoDB已让会使用最'简单'的文件格式存储。下例中,虽然启用了Barracuda文件存储格式,但新建表的文件格式依然是Antelope。
如果启用了独立表空间,我们可以用alter table修改表的行存储格式,可以看到修改为dynamic存储格式后,文件存储格式也变成了Barracuda。
不同行存储格式特点:
InnoDB存储引擎支持4种行存储格式:redundant、compact、dynamic和compressed。每种格式主要特性如下。
行存储格式 | 紧凑存储 | 变长数据 存储增强 | 大索引前缀支持 | 压缩 支持 | 支持的表空间格式 | 需要的文件 存储格式 |
REDUNDANT | No | No | No | No | system, file-per-table | Antelope or Barracuda |
COMPACT | Yes | No | No | No | system, file-per-table | Antelope or Barracuda |
DYNAMIC | Yes | Yes | Yes | No | file-per-table | Barracuda |
COMPRESSED | Yes | Yes | Yes | Yes | file-per-table | Barracuda |
- redundant(冗余存储格式)
此格式主要是为了兼容旧的MySQL版本,使用redundant行存储格式的表。在对待变长字段时(varchar,varbinary,blob,text)。如果变长字段未超过768字节,则会将数据完全存储在主键的索引页中,此时性能还可以。如果变长字段超过768字节,则会将前768个前缀字节存储在叶子节点中,剩余的部分存储在额外溢出页中(overflow pages)。如果定长类型(char)长度超过768字节,则会被编码成变长字段,也采用溢出页存储。大量的溢出页可能导致2个问题:
1.溢出页导致二次读取,大量的溢出页造成查找效率低下。
2.由于原叶子节点也存储了大量变长字段的前缀,导致单个页可以存储的键值变少,造成索引扫描效率降低。
- compact(紧凑存储格式)
Compact格式是为了高效存储数据设计的,其对于变长字段的处理方式与redundant格式类似。但compact格式物理空间的占用要比redundant格式少大约20%,代价是牺牲一部分CPU的性能。因此如果系统的瓶颈是缓存或者磁盘I/O的话,采取compact格式可以一定程度提升性能。但如果瓶颈是CPU,compact格式反而会导致系统更慢。
- dynamic(动态存储格式)
dynamic存储格式主要特点与compact存储格式相同,可以将其视为compact格式的改进版,主要区别在于:
1.对于变长字段,dynamic格式可以将其完全存储在溢出页中,在原节点处保留一个20字节的指针指向溢出页,不再存储768个前缀字节。
2.可以支持大索引前缀,由参数innodb_large_prefix控制,前缀索引最大可以到3072个字节。
3.需要innodb_file_per_table和Barracuda文件存储格式支持。
关于第一点,dynamic格式可以根据页和变长字段的大小自行决定是否将字段存储到溢出页中,如果text和blob长度小于40字节,则dynamic会将其存储在原处,避免溢出页带来的二次查找。如果长度过大,又可以将其完全存储至溢出页,避免原索引页塞入大量数据,导致索引扫描效率降低。
- compressed(压缩存储格式)
compressed格式主要特性与使用要求与dynamic格式相同,主要区别在于额外支持表和索引数据的压缩特性,因此在存储text,blob,varchar类型的数据效率会更高。
行的存储格式可以在create table时使用row_format子句指定,也可以通过alter table的row_format子句进行修改。通过分析系统压力和数据特征,为表选择合适的存储格式可以提升性能。