MySQL 8.4 Release Notes
18.2.3.2 动态表特征
如果一个MyISAM
表包含任何变长列(VARCHAR
, VARBINARY
, BLOB
, 或TEXT
), 或者该表使用了ROW_FORMAT=DYNAMIC
表选项创建。
动态格式比静态格式复杂一些,因为每行都有一个头部指示它的长度。更新操作可能会使一行变长,导致行变得不连续存储。
您可以使用OPTIMIZE TABLE
或myisamchk -r来碎片化一个表。如果您在包含一些变长列的表中频繁访问或修改固定长度列,可能需要将变长列移到其他表以避免碎片化。
动态格式表具有这些特征:
-
所有字符串列都是动态的,除了长度小于四的列。
-
每一行都前置一个位图,指示哪些列包含空字符串(对于字符串列)或零(对于数字列)。这不包括包含
NULL
值的列。如果字符串列在去除尾部空格后长度为零,或者数字列的值为零,它将被标记在位图中,不会保存到磁盘上。非空字符串以一个字节加上字符串内容保存。 -
NULL
列需要额外空间来记录其值是否为NULL
。每个NULL
列占用一个额外的位,向上取整到字节。 -
通常需要的磁盘空间比固定长度表少很多。
-
每一行只使用所需的空间。然而,如果一行变得更长,它将被分割成所需的多个部分,导致行碎片化。在这种情况下,你可能需要定期运行
OPTIMIZE TABLE
或myisamchk -r以提高性能。使用myisamchk -ei来获取表统计信息。 -
比静态格式表更难以在崩溃后重建,因为行可能被分割成多个部分,链接(碎片)可能丢失。
-
动态大小行的预期行长计算公式如下:
3 + (number of columns + 7) / 8 + (number of char columns) + (packed size of numeric columns) + (length of strings) + (number of NULL columns + 7) / 8
每个链接都有6个字节的惩罚。动态行在更新时如果行大小增加,总是会创建新的链接。如果不够大,另一个链接将被创建。你可以使用myisamchk -ed来找到链接的数量。所有链接都可以使用
OPTIMIZE TABLE
或myisamchk -r来删除。