mysql - 允许 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对不起我的英语不好:)
解决方案
的有几个缺陷key_len
。EXPLAIN
- 引擎之间存在差异,但解释没有考虑到这一点。
- 空位可能会或可能不会占用一个完整的字节。不过,3 对 2 是一个方便的线索,即
SMALLINT
isNULL
或NOT 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 的排序。)
推荐阅读
- latex - Latex中具有多行和多列的长表
- javascript - 样式显示时如何添加过渡?
- rust - 将double转换为float时如何确定舍入方向?
- r - 使用 Splashr 等待完整的页面加载
- reactjs - 路径似乎对图像是正确的,但我的 svg 没有显示
- c# - 为什么当我的鼠标统一悬停在一个对象上时,它称它为错误的对象?
- javascript - 我将如何保持用户令牌状态,以便即使刷新我的按钮也会保留在页面上?
- javascript - 获取'/'之前的最后一个值
- sequelize.js - 使用“include.where”获取关联模型时包含关联模型中的所有实例
- ecdsa - 无法验证由 sol-wallet-adapter 签名的消息