设计您的表以最小化它们在磁盘上的空间。通过减少写入和读取磁盘的数据量,这可以带来巨大的改进。较小的表通常在查询执行期间主动处理其内容时需要更少的内存。表数据的任何空间减少也会导致更小的索引,这些索引可以更快地处理。
MySQL 支持许多不同的存储引擎(表类型)和行格式。对于每个表,您可以决定使用哪种存储和索引方法。为您的应用程序选择合适的表格式可以为您带来巨大的性能提升。参见 第 17 章,InnoDB 存储引擎,以及 第 18 章,替代存储引擎。
您可以通过使用此处列出的技术来提高表的性能并最小化存储空间
InnoDB
表默认使用DYNAMIC
行格式创建。要使用除DYNAMIC
以外的行格式,请配置innodb_default_row_format
,或在CREATE TABLE
或ALTER TABLE
语句中显式指定ROW_FORMAT
选项。紧凑型行格式系列(包括
COMPACT
、DYNAMIC
和COMPRESSED
)减少了行存储空间,但增加了某些操作的 CPU 使用量。如果您的工作负载是典型的,受缓存命中率和磁盘速度限制,它很可能是更快的。如果这是一种罕见的情况,受 CPU 速度限制,它可能会更慢。紧凑型行格式系列还在使用可变长度字符集(如
utf8mb3
或utf8mb4
)时优化了CHAR
列的存储。对于ROW_FORMAT=REDUNDANT
,CHAR(
占用N
)N
× 字符集的最大字节长度。许多语言可以用单字节utf8mb3
或utf8mb4
字符来主要书写,因此固定存储长度经常浪费空间。使用紧凑型行格式系列,InnoDB
通过去除尾随空格,为这些列分配了N
到N
× 字符集的最大字节长度范围内的可变存储量。最小存储长度为N
字节,以方便在典型情况下进行就地更新。有关更多信息,请参见 第 17.10 节,“InnoDB 行格式”。为了通过压缩形式存储表数据来进一步最小化空间,在创建
InnoDB
表时指定ROW_FORMAT=COMPRESSED
,或对现有MyISAM
表运行 myisampack 命令。(InnoDB
压缩表可读写,而MyISAM
压缩表只读。)对于
MyISAM
表,如果您没有任何可变长度列(VARCHAR
、TEXT
或BLOB
列),则使用固定大小的行格式。这更快,但可能会浪费一些空间。请参见 第 18.2.3 节,“MyISAM 表存储格式”。即使您有VARCHAR
列,也可以使用CREATE TABLE
选项ROW_FORMAT=FIXED
来提示您希望具有固定长度的行。
表的索引应该尽可能短。这使得识别每一行变得容易且高效。对于
InnoDB
表,主键列会复制到每个辅助索引条目中,因此如果您的辅助索引很多,则短主键会节省大量空间。只创建您需要提高查询性能的索引。索引有利于检索,但会减慢插入和更新操作。如果您主要通过搜索一组列来访问表,则对它们创建单个组合索引,而不是为每列创建单独的索引。索引的第一部分应该是使用最频繁的列。如果您始终在从表中选择时使用多个列,则索引中的第一列应该是重复次数最多的列,以获得更好的索引压缩。
如果一个长字符串列很可能在最初的几个字符上具有唯一的前缀,最好只对该前缀建立索引,使用 MySQL 对列的最左侧部分创建索引的支持(请参见 第 15.1.15 节,“CREATE INDEX 语句”)。较短的索引更快,不仅因为它们需要的磁盘空间更少,而且因为它们也能在索引缓存中获得更多命中,从而减少磁盘查找次数。请参见 第 7.1.1 节,“配置服务器”。
在某些情况下,将经常扫描的表拆分为两个表可能是有益的。这在表是动态格式表且可以利用较小的静态格式表来查找扫描表时相关的行时尤其适用。
使用相同数据类型在不同的表中声明具有相同信息的列,以加快基于相应列的联接速度。
保持列名简单,以便您可以在不同的表中使用相同的名称,并简化联接查询。例如,在名为
customer
的表中,使用列名name
而不是customer_name
。为了使您的名称可移植到其他 SQL 服务器,请考虑将其长度保持在 18 个字符以内。