MySQL将表的行格式指定为固定或动态,具体取决于列数据类型。如果一个表具有变长列数据类型,例如TEXT或VARCHAR,则该行格式为动态;否则,它是固定的。
我的问题是,这两种行格式有什么区别?其中一种比另一种更高效吗?
MySQL将表的行格式指定为固定或动态,具体取决于列数据类型。如果一个表具有变长列数据类型,例如TEXT或VARCHAR,则该行格式为动态;否则,它是固定的。
我的问题是,这两种行格式有什么区别?其中一种比另一种更高效吗?
这个区别只对MyISAM有影响,其他存储引擎不在意这个区别。 编辑:许多用户评论说InnoDB也很在意:链接1 by steampowered,链接2 by Kaan。
对于固定宽度行的MyISAM,有一些优点:
无行碎片:对于变宽度行,可能会将单个行分成多个部分跨越数据文件。这可能会增加磁盘寻道并减慢操作速度。可以使用OPTIMIZE TABLE进行碎片整理,但这并不总是可行的。
数据文件指针大小:在MyISAM中,有一个称为数据文件指针的概念,当需要引用数据文件时会使用它。例如,在索引中引用实际存在行的位置时会使用它。对于固定宽度大小,该指针基于文件中的行偏移量(即,行为1、2、3,而不考虑其大小)。对于变宽度,则基于字节偏移量(即,行可能为1、57、163)。结果是,对于大型表,指针需要更大,从而可能向表添加更多开销。
在出现损坏的情况下更容易修复。由于每行大小相同,如果MyISAM表损坏,修复起来要容易得多,因此您只会丢失实际上损坏的数据。对于变宽度,理论上可能会出现变宽度指针被弄乱的情况,这可能导致数据以不好的方式出错。
现在,固定宽度的主要缺点是会浪费更多空间。例如,您需要使用CHAR字段而不是VARCHAR字段,因此会占用额外的空间。
通常情况下,格式取决于模式,因此您在格式方面没有太多选择。 但是,如果只有几个varchar或单个blob / text,则值得尝试优化。例如,考虑将唯一的varchar切换为char,或将blob拆分为自己的表格。在更新记录时,一个关键的区别就出现了。如果行格式是固定的,那么记录长度不会改变。相比之下,如果行格式是动态的,新数据导致记录长度增加,则会使用链接指向“溢出”数据(即称为溢出指针)。
这会使表格碎片化并且通常会减慢查询速度。有一个命令可以对表格进行碎片整理(OPTIMIZE TABLE),从而在一定程度上缓解这个问题。
MySQL文档中的这个页面似乎与此处的顶部答案相矛盾,因为动态行格式对InnoDB表也有意义:
https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html
固定大小意味着每一行都是完全相同的大小。这意味着如果需要加载数据页面上的第三行,它将恰好位于PageHeader+2*RowSize处,节省了一些访问时间。
为了找到动态记录的开头,必须查阅记录偏移列表,这涉及到额外的间接操作。
简而言之,动态行确实会略微影响性能。不,这并不是一个非常大的问题。如果你认为这可能会成为问题,请进行测试。
静态应该比动态更快、更安全,但缺点是有固定的字符长度。 您可以在这里找到此信息:http://dev.mysql.com/doc/refman/5.0/en/static-format.html