VARCHAR列应该放在MySQL的表定义的末尾吗?

Pro*_*ght 7 mysql varchar rdbms

我听说(来自一位同事,从另一位开发人员那里听到),VARCHAR列应始终放在MySQL的表定义的末尾,因为它们的长度可变,因此可能会减慢查询速度.

我在堆栈溢出上所做的研究似乎与此相矛盾,并且表明列顺序很重要,而对VARCHAR的适用程度有不同的一致性.

他没有具体关于存储引擎,或者它是否仅适用于不经常访问的VARCHAR列.

Iso*_*opp 8

询问关于"MySQL"的问题没有帮助,因为MySQL将存储降级到存储引擎,并且它们以非常不同的方式实现存储.对任何单独的存储引擎提出这个问题是有意义的.

在MEMORY引擎中,不存在可变长度数据类型.VARCHAR会以静默方式更改为CHAR.在您的问题的上下文中:在您的VARCHAR的表定义中,无关紧要.

在MyISAM引擎中,如果表没有任何可变长度数据(VARCHAR,VARBINARY或任何TEXT或BLOB类型),则它是MyISAM的FIXED变体,即记录具有固定的字节长度.这可能会对性能产生影响,尤其是在重复删除和插入数据时(即表不是仅附加表).只要任何可变长度数据类型是表定义的一部分,它就成为MyISAM的DYNAMIC变体,并且MyISAM在内部将除最短CHAR类型之外的任何一种更改为VARCHAR.同样,CHAR/VARCHAR的位置和甚至定义都无关紧要.

在InnoDB引擎中,数据存储在16 KB大小的页面中.页面页脚具有校验和和页眉,其中包括页面目录.页面目录为每一行包含该行相对于页面开头的偏移量.页面还包含可用空间,所有I/O都以页面形式完成.

因此,只要页面中有空闲空间,InnoDB就可以在适当的位置增加VARCHAR,并在页面内移动行,而不会产生任何额外的I/O. 此外,由于所有行都被寻址为(页面编号,页面目录条目),因此页面内的行的移动被定位到页面并且从外部不可见.

这也意味着对于InnoDB来说,行内的列顺序根本不重要.

这些是最常用于MySQL的三个存储引擎,列的顺序对于这三个中的任何一个都无关紧要.可能存在其他更奇特的存储引擎,但事实并非如此.