MySQL中的NULL(性能和存储)

null在MySQL中的性能和存储(空间)明智吗?

例如:

TINYINT:1字节TINYINT W /空1字节+莫名其妙地存储NULL?

这取决于您使用哪个存储引擎。

在MyISAM格式中,每个行标题包含一个位域,每一列用于编码NULL状态。 NULL列仍然占用空间,所以NULL不会减less存储空间。 请参阅https://dev.mysql.com/doc/internals/en/myisam-introduction.html

在InnoDB中,每一列在行标题中都有一个“字段起始偏移量”,它是每列一个或两个字节。 如果该列为NULL,则该字段开始偏移中的高位为开。 在这种情况下,该列根本不需要存储。 所以如果你有很多的NULL,你的存储量应该大大减less。 请参阅https://dev.mysql.com/doc/internals/en/innodb-field-contents.html

编辑:

NULL位是行标题的一部分,你不select添加它们。

我可以想象NULL提高性能的唯一方法是在InnoDB中,如果行包含NULL,则数据页面可能适合更多的行。 所以你的InnoDB缓冲区可能会更有效。

但是如果这在实践中提供了显着的性能优势,我会感到非常惊讶。 担心NULL对性能的影响正处于微观优化领域。 你应该把注意力集中在其他地方,在那些给予更大压力的地方。 例如添加精心select的索引或增加数据库caching分配。

比尔的答案很好,但有些过时了。 使用一个或两个字节来存储NULL 适用于InnoDB REDUNDANT行格式。 由于MySQL 5.0.3 InnoDB使用COMPACT行格式,只使用一位来存储NULL(当然一个字节是最小的),因此:

NULL所需的空间= CEILING(N / 8)字节 ,其中N是一行中NULL列的数量。

  • 0 NULLS = 0字节
  • 1 – 8 NULLS = 1个字节
  • 9 – 16 NULLS = 2个字节
  • 17 – 24 NULLS = 3个字节
  • 等等…

根据关于COMPACT与REDUNDANT的官方MySQL网站:

紧凑的行格式使行存储空间减less了大约20%,代价是增加了某些操作的CPU使用量。 如果您的工作负载是受caching命中率和磁盘速度限制的典型负载,则紧凑格式可能会更快。

使用NULLS优于空string或零:

  • 1 NULL需要1个字节
  • 1空string需要1个字节(假设VARCHAR)
  • 1零需要4个字节(假设INT)

你开始看到这里的节省:

  • 8个NULL需要1个字节
  • 8个空string需要8个字节
  • 8个零需要32个字节

另一方面,我build议在空string或零上使用NULL,因为它们更有组织性,可移植性,并且需要更less的空间。 为了提高性能并节省空间,请专注于使用适当的数据types,索引和查询,而不是使用奇怪的技巧。

更多关于: https : //dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html

我会同意比尔·卡尔文,虽然我会添加这些MySQL技巧 。 第11号具体说明了这一点:

首先,问问自己空string值与空值是否有区别(对于INT字段:0与NULL)。 如果没有理由同时拥有,则不需要NULL字段。 (你知道Oracle认为NULL和空string是相同的吗?)

NULL列需要额外的空间,它们会增加比较语句的复杂性。 只要你可以避免他们。 但是,我知道有些人可能有非常具体的理由有NULL值,这并不总是一件坏事。

另一方面,我仍然在没有大量行的表上使用null,主要是因为我喜欢说NOT NULL的逻辑。

更新稍后再回顾一下,我会补充一点,我个人不喜欢在数据库中使用0而不是NULL,我不推荐它。 如果你不小心,这很容易在你的应用程序中导致大量的误报。

看看我在这个主题的post (简而言之,如果可能,答案是避免NULL)

dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html

MySQL可以对col_name = constant_value使用col_name IS NULL来执行相同的优化。 例如,MySQL可以使用索引和范围来search带有IS NULL的NULL