mysql - 允许 NULL 的 InnoDB 索引大小 (MySQL)

标签 mysql innodb

我想知道是否有人在 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 个字节。

附言抱歉我的英语不好:)

最佳答案

EXPLAINkey_len 有几个缺陷。

  • Engine 之间存在差异,但 Explain 并未考虑这些差异。
  • 空位可能占用也可能不占用一个完整字节。尽管如此,3 vs 2 还是一个方便的线索,表明 SMALLINTNULLNOT NULL
  • VAR... 实际上占用的空间量是可变的。
  • InnoDB 的每一列都有一个 1 或 2 字节的前缀;没有提到。
  • key_len 通常 说明使用 = 测试的任何列。如果还有可以使用部分索引的“范围”测试(BETWEEN>LIKE 'foo%' 等), key_len 不表示这样。
  • 对于 GROUP BYORDER 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/

相关文章:

python - 我怎样才能让 tormysql 做插入?

mysql - 数据库,每个用户一张表还是一张大表?

mysql - InnoDB 中是否有估算索引大小的公式?

mysql - Innodb 显示不正确的计数(id)

php - 使用 php 数据库中的数据填充 HTML 表单的一部分

mysql - Laravel MySQL DB 在长时间处理后未更新

php - 查询显示月份和年份下的所有帖子标题

mysql - 为什么 MySQL InnoDB 插入这么慢?

mysql - InnoDB 还是 MyISAM?

mysql - 虚假外键约束失败