优化 InnoDB 表的存储布局
- 在 InnoDB 中,具有长 PRIMARY KEY(具有冗长值的单个列或者形成长复合值的多个列)浪费了大量磁盘空间。在指向同一行的所有辅助索引记录中,行的主键值重复。如果主键很长,则创建一个 AUTO_INCREMENT 列作为主键。
- 使用 VARCHAR 数据类型而不是 CHAR 来存储可变长度字符串或具有许多 NULL 值的列。即使字符串较短或其值为 NULL,
CHAR(N)
列也始终使用 N 个字符来存储数据。较小的表更适合缓冲池并减少磁盘 I / O.
当使用 COMPACT 行格式(默认的 InnoDB 格式)和可变长度字符集(如 utf8 或 sjis)时,
CHAR(N)
列占用可变的空间量,但仍至少占用 N 个字节。
- 对于大型表或包含大量重复文本或数字数据的表,请考虑使用 COMPRESSED 行格式。将数据放入缓冲池或执行全表扫描需要较少的磁盘 I / O. 在做出永久性决策之前,请使用 COMPRESSED 与 COMPACT 行格式测量可以实现的压缩量。警告: 基准测试很少显示比 2:1 压缩更好,并且缓冲区中有很多开销用于 COMPRESSED。
- 一旦数据达到稳定大小,或者增长的表增加了几十或几百兆字节,请考虑使用 OPTIMIZE TABLE 语句重新组织表并压缩任何浪费的空间。重组的表需要较少的磁盘 I / O 来执行全表扫描。这是一种简单的技术,可以在其他技术(如改进索引使用或调整应用程序代码)不切实际时提高性能。警告 :无论表大小如何,OPTIMIZE TABLE 都应该很少执行。这是因为它的成本很高,并且很少能够提高表格的价值。InnoDB 相当擅长保持其 B +树免于浪费大量空间。
OPTIMIZE TABLE 复制表的数据部分并重建索引。其好处来自于改进了索引中数据的打包,减少了表空间和磁盘上的碎片。好处取决于每个表中的数据。你可能会发现某些人而不是其他人获得了显着的收益,或者在你下次优化表之前,收益会随着时间的推移而降低。如果表很大或者正在重建的索引不适合缓冲池,则此操作可能会很慢。向表中添加大量数据后的第一次运行通常比以后的运行慢得多。