我想知道是否有人在MySQL文档中找到有关InnoDB的确认信息,即允许索引中为NULL的列需要额外的1个字节?
示例:创建一列SMALLINT UNSIGNED DEFAULT NULL;
(2个字节)。索引使用3个字节(不考虑PK链接)。
不允许使用NULL的同一列:SMALLINT UNSIGNED NOT NULL
;索引应为2个字节。
UPD:我在文档中找到了这个: “由于密钥存储格式的原因,可以为NULL的列的密钥长度比不是NULL的列大一。” 但我还是不明白,索引大小是否比NULLable列大1个字节。
P.S。对不起,我的英语不好:)
答案 0 :(得分:5)
key_len
的{{1}}中存在一些缺陷。
EXPLAIN
是SMALLINT
或NULL
的方便提示。NOT NULL
实际上占用了可变的空间。VAR...
通常说明使用key_len
测试的所有列。如果还存在可以使用部分索引的“范围”测试(=
,BETWEEN
,>
,则key_len不会表明这样做。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的顺序。)