null 在 MySQL 中到底对性能和存储(空间)有什么影响?

例如:

小整数:1个字节tinyint w/null 1字节 +以某种方式存储空?

有帮助吗?

解决方案

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

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

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

修改

NULL位是行标题的一部分,您不选择添加它们。

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

但如果这在实践中提供显着的性能优势,我会感到非常惊讶。担心NULL对性能的影响属于微优化领域。你应该将注意力集中在其他地方,在那些能够带来更大收益的领域。例如,添加精心选择的索引或增加数据库缓存分配。

其他提示

比尔的回答很好,但有点过时了。使用一个或两个字节来存储 NULL 适用 仅有的 到 InnoDB REDUNDANT 行格式。自 MySQL 5.0.3 InnoDB 使用 袖珍的 row 格式只使用一位来存储 NULL(当然最少一个字节),因此:

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

  • 0 NULL = 0 字节
  • 1 - 8 个 NULL = 1 字节
  • 9 - 16 个 NULL = 2 字节
  • 17 - 24 个 NULL = 3 字节
  • ETC...

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

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

使用 NULL 相对于空字符串或零的优点:

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

您开始看到这里的节省:

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

另一方面,我建议在空字符串或零上使用 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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top