允许 NULL 的 InnoDB 索引大小 (MySQL)

InnoDB index size with NULLs allowed (MySQL)

我想知道是否有人在 MySQL 文档中找到确认,对于 InnoDB,索引中允许 NULL 的列需要 1 个额外字节?

示例:创建列 SMALLINT UNSIGNED DEFAULT NULL;(2 个字节)。索引使用3个字节(不考虑PK链接)

不允许NULL的同一列:SMALLINT UNSIGNED NOT NULL;索引将是它应该的 - 2 个字节。

UPD:我在文档中找到了这个: "Due to the key storage format, the key length is one greater for a column that can be NULL than for a NOT NULL column." 但是,我仍然不明白,对于 NULLable 列,索引大小是否大于 1 个字节。

P.S。抱歉我的英语不好:)

EXPLAINkey_len 有几个缺陷。

  • 引擎之间存在差异,但 Explain 并未考虑这些差异。
  • 空位可能占用也可能不占用一个完整字节。不过,3 对 2 是一个方便的线索,表明 SMALLINTNULLNOT NULL
  • VAR... 实际上需要可变数量的 space.
  • InnoDB 每列都有一个 1 或 2 字节的前缀;没有提到。
  • key_len 通常 说明使用 = 测试的任何列。如果还有"range"测试(BETWEEN>LIKE 'foo%', etc)可以使用部分索引,key_len不表示这样。
  • 同上使用 GROUP BYORDER BY 的部分索引。

您可以通过 EXPLAIN FORMAT=JSON SELECT ....

获得 更多 信息(但仍然不是 'everyting')

逻辑上,如果不是现实,2字节SMALLINT中没有NULL的空间。因此,需要更多 space -- 至少一位。

有两个不同的问题 -- 索引 BTree 的大小和查询期间使用的数据结构。

我认为 NULL 的额外字节或位不值得担心。相反,最好说 NOT NULL,除非您对 NULL 有 "business logic" 要求(无值,N/A,尚未指定,等等)。然后让 table、索引等根据需要消耗额外的位或字节。

我认为(没有充分证实)InnoDB 没有额外的 space 空位——它是每列前缀的 8 位或 16 位之一。

请注意,在 InnoDB 中,索引 BTree 与数据 BTree 本质上相同。 (PRIMARY KEY 是数据 BTree 的排序。)