10.4.1 数据大小优化
设计表格以减少磁盘空间。这样可以通过减少磁盘写入和读取量来获得巨大改进。较小的表格通常在查询执行期间需要更少的主内存空间。任何表格数据的空间减少也会导致更快地处理索引。
MySQL 支持多种存储引擎(表类型)和行格式。对于每个表,可以决定使用哪种存储和索引方法。选择合适的表格格式可以给您带来很大的性能提高。见第17章,InnoDB 存储引擎,和第18章,Alternative 存储引擎。
通过以下技术,可以使表格性能更好、存储空间更小:
-
尽量使用最小的数据类型。MySQL 有许多专门的类型可以节省磁盘空间和内存。例如,如果可能,可以使用较小的整数类型来获取较小的表。
MEDIUMINT
通常比INT
更好,因为一个MEDIUMINT
列占用空间少25%。 -
如果可能,声明列为
NOT NULL
。这样可以使 SQL 操作更快,通过更好的索引使用和避免每个值是否为NULL
的测试 overhead。你也可以节省一些存储空间,一位 per 列。如果你真的需要表中的NULL
值,使用它们。只是不要默认设置允许每列都有NULL
值。
-
InnoDB
表使用默认的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
个字节,以便在典型情况下进行in-place更新。更多信息,请参见第17.10节,“InnoDB行格式”. -
为了进一步减少空间,创建
InnoDB
表时指定ROW_FORMAT=COMPRESSED
,或者在现有MyISAM
表上运行myisampack命令。(InnoDB
压缩表是可读写的,而MyISAM
压缩表是只读的。) -
对于
MyISAM
表,如果您没有变长列(VARCHAR
、TEXT
或BLOB
列),固定大小行格式将被使用。这速度更快,但可能浪费一些空间。见第18.2.3节,“MyISAM 表存储格式”。您可以使用CREATE TABLE
选项ROW_FORMAT=FIXED
来暗示您想要固定长度行,即使有VARCHAR
列。
索引
-
表的主键应该尽量短。这样可以轻松地和高效地识别每一行。对于
InnoDB
表,主键列在每个次要索引条目中被复制,所以如果您有很多次要索引,短的主键可以节省很大空间。 -
只创建需要提高查询性能的索引。索引对于检索操作很好,但会 slows down 插入和更新操作。如果您主要通过搜索多个列来访问表,创建一个组合索引,而不是单独为每个列创建索引。索引的第一个部分应该是最常用的列。如果您总是使用多个列从表中选择数据,那么索引的第一个列应该是具有最多重复值的列,以获得更好的索引压缩。
-
如果很可能长字符串列在前几个字符上有唯一前缀,创建只索引这个前缀,使用 MySQL 的支持创建索引的左部分(见第15.1.15节,“CREATE INDEX 语句”)。更短的索引不仅因为它们需要更少的磁盘空间,还因为它们也会在索引缓存中更多地命中,减少磁盘寻道次数。见第7.1.1节,“服务器配置”。
-
在某些情况下,扫描非常频繁的表可以被分割成两个表。这尤其适用于动态格式表,如果可能使用更小的静态格式表来找到相关行时。
-
将具有相同信息的列在不同表中声明相同数据类型,以加速基于相应列的连接操作。
-
保持列名简单,以便在不同的表中使用相同的名称,简化连接查询。例如,在一个名为
customer
的表中,使用name
作为列名,而不是customer_name
。为了使名称在其他 SQL 服务器上可移植,考虑将它们保持在 18 个字符以下。
-
通常情况下,尽量保持所有数据非冗余(遵循数据库理论中的第三范式)。而不是重复长字符串,如名称和地址,分配唯一的 ID,根据需要在多个小表中重复这些 ID,并在查询中通过 join 子句引用 ID。
-
如果速度比磁盘空间和维护多个数据副本的成本更重要,例如,在业务智能场景中分析大型表中的所有数据,你可以放松 normalization 规则,重复信息或创建摘要表以获得更多速度。