我想知道是否有人在 MySQL 文档中找到确认,对于 InnoDB,索引中允许 NULL 的列占用 1 个额外字节?
示例:创建列 SMALLINT UNSIGNED DEFAULT NULL;
(2 个字节)。索引使用3个字节(不考虑PK链接)。
同一列不允许NULL:SMALLINT UNSIGNED NOT NULL
;索引将是它应该的 - 2 个字节。
UPD:我在文档中找到了这个: “由于 key 存储格式,可以为 NULL 的列的 key 长度比 NOT NULL 列的 key 长度长一倍。” 但是,我仍然不明白,对于 NULLable 列,索引大小是否大于 1 个字节。
附言抱歉我的英语不好:)
最佳答案
EXPLAIN
的key_len
有几个缺陷。
- Engine 之间存在差异,但 Explain 并未考虑这些差异。
- 空位可能占用也可能不占用一个完整字节。尽管如此,3 vs 2 还是一个方便的线索,表明
SMALLINT
是NULL
或NOT NULL
。 VAR...
实际上占用的空间量是可变的。- InnoDB 的每一列都有一个 1 或 2 字节的前缀;没有提到。
key_len
通常 说明使用=
测试的任何列。如果还有可以使用部分索引的“范围”测试(BETWEEN
、>
、LIKE 'foo%' 等)
, key_len 不表示这样。- 对于
GROUP BY
和ORDER BY
使用部分索引也是如此。
通过使用 EXPLAIN FORMAT=JSON SELECT ...
,您可以获得更多信息(但仍然不是“所有”)。
逻辑上,如果不是在现实中,在 2 字节的 SMALLINT
中没有 NULL
的空间。因此,需要更多空间 - 至少一位。
有两个不同的问题——索引 BTree 的大小,以及查询期间使用的数据结构。
我认为 NULL
的额外字节或位不值得担心。相反,最好说 NOT NULL
除非您对 NULL
有“业务逻辑”要求(无值、N/A、尚未指定等) ).然后让表、索引等根据需要消耗额外的位或字节。
我认为(没有充分证实)InnoDB 没有为空位占用额外的空间——它是每列前缀的 8 位或 16 位之一。
请注意,在 InnoDB 中,索引 BTree 本质上与数据 BTree 相同。 (PRIMARY KEY
是数据 BTree 的排序。)
关于mysql - 允许 NULL 的 InnoDB 索引大小 (MySQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53463155/