如何通过EXPLAIN 执行计划中的 key_len 计算出联合索引到底哪几个字段生效

举报
developer_Li 发表于 2026/08/10 12:28:36 2026/08/10
【摘要】 计算 key_len 就像做加法题,我们需要把生效索引列的 【数据类型长度】 + 【NULL 标记】 + 【变长类型标记】 全部加在一起。 一、 核心计算公式与标准基础数据类型固定长度整数类:TINYINT = 1 字节 | SMALLINT = 2 字节 | INT = 4 字节 | BIGINT = 8 字节。时间类(MySQL 5.6 之后):DATE = 3 字节 | TIMESTA...

计算 key_len 就像做加法题,我们需要把生效索引列的 【数据类型长度】 + 【NULL 标记】 + 【变长类型标记】 全部加在一起。

一、 核心计算公式与标准

  1. 基础数据类型固定长度
    整数类:TINYINT = 1 字节 | SMALLINT = 2 字节 | INT = 4 字节 | BIGINT = 8 字节。
    时间类(MySQL 5.6 之后):DATE = 3 字节 | TIMESTAMP = 4 字节 | DATETIME = 5 字节。
  2. 字符串类型长度(关键:看字符集)字符串占用的字节数 = 定义的字符长度 × 字符集单字符最大字节数:
    如果使用 gbk:每个字符最多占 2 字节。
    如果使用 utf8:每个字符最多占 3 字节。
    如果使用 utf8mb4(目前最通用):每个字符最多占 4 字节。例:VARCHAR(20) 且字符集为 utf8mb4,基础长度 = 20 × 4 = 80 字节。
  3. 附加修饰符(“隐藏”的字节)
    NULL 属性标记:如果该字段允许为 NULL(没有设置 NOT NULL),MySQL 需要额外用 1 字节来存储 NULL 标记。
    变长类型标记:如果是 VARCHAR 等变长字符串,MySQL 需要额外用 2 字节来记录字符串的实际物理长度。

二、 实战演练:一步步推算

CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20) DEFAULT NULL, -- 允许为 NULL,变长 age INT NOT NULL, -- 不允许为 NULL,定长 PRIMARY KEY (id), KEY idx_name_age (name, age) -- 联合索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 采用 utf8mb4 字符集

第一步:单独计算每个字段的索引长度

  • name 字段的长度:
    • 基础长度:20 (字符) × 4 (utf8mb4) = 80 字节
    • 允许为 NULL:+1 字节
    • 变长字符串(VARCHAR):+2 字节
    • 单列总计:80 + 1 + 2 = 83 字节
  • age 字段的长度:
    • 基础长度:INT 类型 = 4 字节
    • 不允许为 NULL(NOT NULL):+0 字节
    • 定长类型:+0 字节
    • 单列总计:4 字节

第二步:看 EXPLAIN 结果做加法

当你运行不同的查询语句并查看 EXPLAIN 时,可以通过 key_len 逆向推导:

场景 1:完全匹配

EXPLAIN SELECT * FROM users WHERE name = 'Bob' AND age = 23;

  • key_len 结果:87
  • 推导逻辑:83 (name) + 4 (age) = 87。说明 name 和 age 两个字段都走了解析和索引过滤。

场景 2:最左匹配,漏掉右边

EXPLAIN SELECT * FROM users WHERE name = 'Bob';

  • key_len 结果:83
  • 推导逻辑:正好等于 name 字段的长度。说明只有 name 走了解索引。

场景 3:范围查询导致右边失效

EXPLAIN SELECT * FROM users WHERE name LIKE 'B%' AND age = 23;

  • key_len 结果:83
  • 推导逻辑:虽然条件里写了 age = 23,但 key_len 只有 83。因为 name 使用了模糊范围查询(LIKE ‘B%’),导致在 B+ 树指路时,右边的 age 无法再利用索引进行有序过滤了。此时只有 name 索引生效。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。