如果一个 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字节的罚款。当更新导致行扩展时,动态行将被链接。每个新链接至少需要20字节,因此下一个扩展可能会在同一个链接中。如果不是,另一个链接将被创建。你可以使用myisamchk -ed找到链接的数量。所有链接可以使用
OPTIMIZE TABLE
或myisamchk -r删除。