首页 > 解决方案 > 允许 NULL 的 InnoDB 索引大小(MySQL)

问题描述

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

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

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

UPD:我在文档中找到了这一点:“由于密钥存储格式的原因,可以为 NULL 的列的密钥长度比 NOT NULL 列的密钥长度大一。” 但是,我仍然不明白,索引大小是否比 NULLable 列大 1 个字节。

PS对不起我的英语不好:)

标签: mysqlinnodb

解决方案


的有几个缺陷key_lenEXPLAIN

  • 引擎之间存在差异,但解释没有考虑到这一点。
  • 空位可能会或可能不会占用一个完整的字节。不过,3 对 2 是一个方便的线索,即SMALLINTisNULLNOT NULL.
  • VAR...实际上占用了可变数量的空间。
  • InnoDB` 每列都有一个 1 或 2 字节的前缀;没有提到。
  • key_len 通常占使用 测试的任何列=。如果还有一个“范围”测试 ( BETWEEN, >,LIKE 'foo%', etc)可以使用部分索引,则 key_len 不表示这样。
  • 同上使用 和 的部分GROUP BY索引ORDER BY

您可以使用.EXPLAIN FORMAT=JSON SELECT ...

从逻辑上讲,如果不是在现实NULL中,2-byte中没有空间SMALLINT。所以,需要更多的空间——至少一点。

有两个独立的问题——索引 BTree 的大小和查询期间使用的数据结构。

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

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

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


推荐阅读