15.2.3.2 动态表特性

MyISAM 如果表包含任何可变长度列(VARCHARVARBINARYBLOBTEXT),或者如果表是使用ROW_FORMAT=DYNAMICtable 选项 创建的, 则使用动态存储格式。

动态格式比静态格式稍微复杂一点,因为每一行都有一个标头来指示它有多长。当一行因更新而变得更长时,它可能会变得碎片化(存储在不连续的片段中)。

您可以使用OPTIMIZE TABLEmyisamchk -r对表进行碎片整理。如果在还包含一些可变长度列的表中有经常访问或更改的固定长度列,那么将可变长度列移动到其他表以避免碎片化可能是个好主意。

动态格式表具有以下特征:

  • 除长度小于四的字符串列外,所有字符串列都是动态的。

  • 每行前面都有一个位图,指示哪些列包含空字符串(对于字符串列)或零(对于数字列)。这不包括包含NULL值的列。如果删除尾随空格后字符串列的长度为零,或者数字列的值为零,则它会在位图中标记并且不会保存到磁盘。非空字符串保存为长度字节加上字符串内容。

  • NULL列需要行中的额外空间来记录它们的值是否为 NULL. 每NULL列额外占用一位,四舍五入到最接近的字节。

  • 通常需要比固定长度表少得多的磁盘空间。

  • 每行只使用所需的空间。但是,如果一行变大,它会根据需要分成许多块,从而导致行碎片。例如,如果您使用扩展行长度的信息更新行,则该行会变得碎片化。在这种情况下,您可能必须不时运行OPTIMIZE TABLEmyisamchk -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 TABLEmyisamchk -r删除所有链接。