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

时间:2018-11-24 23:08:29

标签: mysql innodb

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

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

不允许使用NULL的同一列:SMALLINT UNSIGNED NOT NULL;索引应为2个字节。

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

P.S。对不起,我的英语不好:)

1 个答案:

答案 0 :(得分:5)

key_len的{​​{1}}中存在一些缺陷。

  • 引擎之间存在差异,但Explain并未考虑这些差异。
  • 空位可能占用也可能不会占用完整字节。不过,3 vs 2是EXPLAINSMALLINTNULL的方便提示。
  • NOT NULL实际上占用了可变的空间。
  • InnoDB`每列的前缀为1或2字节;没有提到。
  • VAR... 通常说明使用key_len测试的所有列。如果还存在可以使用部分索引的“范围”测试(=BETWEEN>,则key_len不会表明这样做。
  • Ditto用于将部分索引用于LIKE 'foo%', etc)GROUP BY

您可以使用ORDER BY获得更多信息(但仍然不是“一切”)。

从逻辑上讲,如果实际上不是,则2字节的EXPLAIN FORMAT=JSON SELECT ...中没有NULL的空间。因此,需要更多空间-至少一位。

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

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

我认为(没有足够的确认)InnoDB不会为null位占用额外的空间-它是为每列加上前缀的8位或16位之一。

请注意,在InnoDB中,索引BTree与数据BTree本质上相同。 (并且NULL是数据BTree的顺序。)