在MySQL中,性能和存储(空间)明智地归零是什么?
例如:
TINYINT:1字节TINYINT w / NULL 1字节+以某种方式存储NULL?
Answers:
这取决于您使用的存储引擎。
在MyISAM格式中,每个行标题都包含一个位域,每个列的每个位都具有一位以编码NULL状态。NULL列仍会占用空间,因此NULL不会减少存储量。参见https://dev.mysql.com/doc/internals/en/myisam-introduction.html
在InnoDB中,每一列在行标题中都有一个“字段开始偏移量”,每列一个或两个字节。如果该列为NULL,则该字段起始偏移量的高位为ON。在这种情况下,该列根本不需要存储。因此,如果您有很多NULL,则应该大大减少存储空间。参见https://dev.mysql.com/doc/internals/en/innodb-field-contents.html
编辑:
NULL位是行标题的一部分,您不选择添加它们。
我可以想象NULL提高性能的唯一方法是,在InnoDB中,如果行中包含NULL,则数据页可以容纳更多行。因此,您的InnoDB缓冲区可能更有效。
但是,如果这在实践中提供了显着的性能优势,我将感到非常惊讶。担心NULL对性能的影响在于微优化领域。您应该将注意力集中在其他方面,这些领域可以带来更大的收益。例如,添加精心选择的索引或增加数据库缓存分配。
比尔的回答很好,但是有点过时了。用于存储NULL使用一个或两个字节应用于仅InnoDB的冗余行格式。由于MySQL 5.0.3 InnoDB使用COMPACT行格式,该格式仅使用一位存储NULL(当然,最小字节是一个字节),因此:
NULL所需的空间= CEILING(N / 8)个字节,其中N是一行中NULL列的数量。
根据有关COMPACT vs REDUNDANT的MySQL官方网站:
紧凑的行格式以某些操作增加CPU使用为代价,将行存储空间减少了约20%。如果您的工作量是典型的工作量,受缓存命中率和磁盘速度的限制,那么紧凑格式可能会更快。
您开始在这里看到节省的地方:
另一方面,我建议对空字符串或零使用NULL,因为它们更具组织性,可移植性并且需要较少的空间。为了提高性能并节省空间,请专注于使用适当的数据类型,索引和查询,而不要使用怪异的技巧。
有关更多信息:https : //dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
我同意Bill Karwin的观点,尽管我会添加这些MySQL技巧。11号专门解决了这个问题:
首先,问问自己,具有空字符串值和NULL值之间是否有任何区别(对于INT字段:0与NULL)。如果没有理由同时拥有两者,则不需要NULL字段。(您知道Oracle认为NULL和空字符串相同吗?)
NULL列需要额外的空间,它们会增加比较语句的复杂性。只要有可能就避开它们。但是,据我了解,有些人可能有非常特定的原因拥有NULL值,这并不总是一件坏事。
另一方面,我仍然在没有大量行的表上使用null,主要是因为我喜欢说NOT NULL的逻辑。
更新, 稍后再讨论,我会补充一点,我个人不希望在数据库中使用0而不是NULL,因此我不建议这样做。如果您不小心,很容易在应用程序中导致很多误报。
dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html
MySQL可以对col_name IS NULL执行与col_name = constant_value相同的优化。例如,MySQL可以使用索引和范围使用IS NULL搜索NULL。