允许 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。抱歉我的英语不好:)
EXPLAIN
的 key_len
有几个缺陷。
- 引擎之间存在差异,但 Explain 并未考虑这些差异。
- 空位可能占用也可能不占用一个完整字节。不过,3 对 2 是一个方便的线索,表明
SMALLINT
是 NULL
或 NOT NULL
。
VAR...
实际上需要可变数量的 space.
- InnoDB 每列都有一个 1 或 2 字节的前缀;没有提到。
key_len
通常 说明使用 =
测试的任何列。如果还有"range"测试(BETWEEN
、>
、LIKE 'foo%', etc)
可以使用部分索引,key_len不表示这样。
- 同上使用
GROUP BY
和 ORDER 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 的排序。)
我想知道是否有人在 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。抱歉我的英语不好:)
EXPLAIN
的 key_len
有几个缺陷。
- 引擎之间存在差异,但 Explain 并未考虑这些差异。
- 空位可能占用也可能不占用一个完整字节。不过,3 对 2 是一个方便的线索,表明
SMALLINT
是NULL
或NOT NULL
。 VAR...
实际上需要可变数量的 space.- InnoDB 每列都有一个 1 或 2 字节的前缀;没有提到。
key_len
通常 说明使用=
测试的任何列。如果还有"range"测试(BETWEEN
、>
、LIKE 'foo%', etc)
可以使用部分索引,key_len不表示这样。- 同上使用
GROUP BY
和ORDER BY
的部分索引。
您可以通过 EXPLAIN FORMAT=JSON SELECT ...
.
逻辑上,如果不是现实,2字节SMALLINT
中没有NULL
的空间。因此,需要更多 space -- 至少一位。
有两个不同的问题 -- 索引 BTree 的大小和查询期间使用的数据结构。
我认为 NULL
的额外字节或位不值得担心。相反,最好说 NOT NULL
,除非您对 NULL
有 "business logic" 要求(无值,N/A,尚未指定,等等)。然后让 table、索引等根据需要消耗额外的位或字节。
我认为(没有充分证实)InnoDB 没有额外的 space 空位——它是每列前缀的 8 位或 16 位之一。
请注意,在 InnoDB 中,索引 BTree 与数据 BTree 本质上相同。 (PRIMARY KEY
是数据 BTree 的排序。)