MySQL EXPLAIN中的key_len索引使用实战解析

 更新时间:2025年11月19日 08:46:35   作者:爱学习的懒洋洋  
在MySQL执行计划中,key_len表示查询实际使用索引的字节长度,今天通过本文给大家介绍MySQL EXPLAIN中的key_len索引使用实战解析,感兴趣的朋友跟随小编一起看看吧

深入解析MySQL执行计划中最关键的指标之一,助你快速定位索引优化点,提升查询性能!

一、key_len:索引使用的精准标尺

在MySQL执行计划中,key_len表示查询实际使用索引的字节长度。这个指标是索引优化的核心,它能揭示:

  • 复合索引使用深度:显示使用了复合索引的前几列
  • 索引利用效率:值越大,索引利用率越高
  • 索引失效检测:NULL值表示索引未被使用
  • 数据类型成本:不同数据类型在索引中的开销

二、key_len计算的核心规则(重点掌握!)

1. 基础计算规则

key_len = 数据类型基础长度 + NULL标记(1字节) + 变长类型额外开销(2字节)

2. 常用数据类型计算表(utf8mb4环境)

数据类型基础长度NULL开销VARCHAR开销NOT NULL示例NULL示例
INT4字节+1字节-45
BIGINT8字节+1字节-89
TINYINT1字节+1字节-12
FLOAT4字节+1字节-45
DOUBLE8字节+1字节-89
DATE3字节+1字节-34
DATETIME8字节+1字节-89
TIMESTAMP4字节+1字节-45
CHAR(10)10×字符集字节+1字节-40 (utf8mb4)41 (utf8mb4)
VARCHAR(50)50×字符集字节+1字节+2字节202 (utf8mb4)203 (utf8mb4)

核心要点

VARCHAR类型在索引中固定增加2字节长度前缀(实际行存储时规则不一致:≤255字符+1字节,>255字符+2字节)

字符集直接影响长度:utf8mb4=4字节/字符,latin1=1字节/字符

NULL列增加1字节开销

三、key_len实战解析:从案例学优化

案例1:复合索引使用深度判断

-- 表结构
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,  -- key_len:50×4+2=202
  age TINYINT NOT NULL,        -- key_len:1
  email VARCHAR(100) NOT NULL, -- key_len:100×4+2=402
  INDEX idx_profile (name, age, email)
) CHARSET=utf8mb4;

-- 场景1:仅使用name列
EXPLAIN SELECT * FROM users WHERE name = 'John';
-- key_len = 202(复合索引第一列)

-- 场景2:使用前两列
EXPLAIN SELECT * FROM users WHERE name = 'John' AND age = 30;
-- key_len = 203(202+1)

-- 场景3:使用所有列
EXPLAIN SELECT * FROM users WHERE name = 'John' AND age = 30 AND email = 'john@example.com';
-- key_len = 605(202+1+402)

案例2:字符集对key_len的影响

-- latin1字符集对比
CREATE TABLE logs_latin1 (
  message VARCHAR(100) NOT NULL
) CHARSET=latin1;

CREATE TABLE logs_utf8mb4 (
  message VARCHAR(100) NOT NULL
) CHARSET=utf8mb4;

EXPLAIN SELECT * FROM logs_latin1 WHERE message = 'error';
-- key_len = 102 (100×1 + 2)

EXPLAIN SELECT * FROM logs_utf8mb4 WHERE message = 'error';
-- key_len = 402 (100×4 + 2)

案例3:NULL值的隐藏成本

-- 允许NULL的列
ALTER TABLE users MODIFY age TINYINT NULL;

-- 相同查询条件
EXPLAIN SELECT * FROM users WHERE name = 'John' AND age = 30;
-- key_len = 204(202+1+1,比非NULL多1字节)

四、key_len揭示的三大优化机会

1. 复合索引优化(核心!)

当key_len < 索引总长度时:

  • 问题:索引未充分利用
  • 解决方案
    -- 1. 补充缺失查询条件
    SELECT ... WHERE col1=1 AND col2=2 AND col3=3
    
    -- 2. 重建索引(高频查询列前置)
    ALTER TABLE orders DROP INDEX idx_old;
    ALTER TABLE orders ADD INDEX idx_new (status, user_id, created_at);
    
    -- 3. 使用覆盖索引
    SELECT indexed_columns FROM table WHERE ...
    

2. VARCHAR列优化策略

-- 方案1:前缀索引(减少长度)
ALTER TABLE products ADD INDEX (description(20)); 
-- key_len从402降为82(VARCHAR(100)→20×4+2)

3. 消除NULL存储开销

-- 优化前(允许NULL)
ALTER TABLE users MODIFY phone VARCHAR(20) NULL;
-- key_len=20×4+2+1=83

-- 优化后(禁止NULL)
ALTER TABLE users 
  MODIFY phone VARCHAR(20) NOT NULL DEFAULT '';
-- key_len=82(节省1字节/行)

五、高级诊断技巧

1. EXPLAIN FORMAT=JSON(推荐)

EXPLAIN FORMAT=JSON 
SELECT * FROM users WHERE name='Lisa';

/* 输出片段 */
{
  "query_block": {
    "table": {
      "key_length": 202,
      "used_key_parts": ["name"],
      // ...其他信息
    }
  }
}

2. 性能优化检查清单

  • 检查key_len是否接近索引长度
  • 确认复合索引是否满足最左前缀原则
  • 分析VARCHAR列长度是否合理
  • 检查是否有不必要的NULL列
  • 对比不同字符集下的索引大小

六、总结:key_len优化四原则

  • 追求最大key_len:值越接近索引总长度,索引利用越充分
  • 警惕NULL开销:每允许一个NULL列,key_len增加1字节
  • VARCHAR成本控制:长文本字段优先考虑前缀索引或哈希
  • 最左前缀原则:确保查询条件从复合索引最左侧开始

终极技巧:当发现key_len显著小于索引长度时,立即检查:

  • 是否缺少必要查询条件?
  • 索引列顺序是否合理?
  • 是否存在数据类型转换?
  • 字符集选择是否合适?

到此这篇关于MySQL EXPLAIN中的key_len索引使用实战解析的文章就介绍到这了,更多相关mysql explain key_len使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL全面瓦解之查询的过滤条件详解

    MySQL全面瓦解之查询的过滤条件详解

    这篇文章主要给打大家介绍了关于MySQL全面瓦解之查询的过滤条件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • SQL字段拼接成新字段几种常见的方法

    SQL字段拼接成新字段几种常见的方法

    这篇文章主要给大家介绍了关于SQL字段拼接成新字段几种常见的方法,如我们在选择商品的时候不止需要知道商品的名字,还需要商品代码型号等,这个时候需要把这些字段拼接为一个字段进行操作或者输出,需要的朋友可以参考下
    2023-08-08
  • mysql索引过长Specialed key was too long的解决方法

    mysql索引过长Specialed key was too long的解决方法

    在创建要给表的时候遇到一个有意思的问题,提示Specified key was too long; max key length is 767 bytes,本文就来介绍一下解决方法,如果你也遇到此类问题,可以参考一下
    2021-11-11
  • 一起了解了解MySQL存储引擎

    一起了解了解MySQL存储引擎

    大家好,本篇文章主要讲的是一起了解了解MySQL存储引擎,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • MySQL插入、更新与删除表中数据实现方式

    MySQL插入、更新与删除表中数据实现方式

    本文介绍了MySQL数据插入、更新和删除的操作方法,包括直接添加、没有字段名添加、部分字段添加、多行添加等插入方法,UPDATE语句更新记录,DELETE语句删除记录,以及TRUNCATE语句删除表中所有记录,最后总结了TRUNCATE与DELETE的区别
    2026-04-04
  • MySQL8.0与MySQL5.7的区别详解

    MySQL8.0与MySQL5.7的区别详解

    MySQL8.0是2018年4月20日发布的全球最受欢迎的开源数据库的一个非常令人兴奋的新版本,下面这篇文章主要给大家介绍了关于MySQL8.0与MySQL5.7区别的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • MySQL入门(二) 数据库数据类型详解

    MySQL入门(二) 数据库数据类型详解

    这个数据库所遇到的数据类型今天统统在这里讲清楚了,以后在看到什么数据类型,咱度应该认识,对我来说,最不熟悉的应该就是时间类型这块了。但是通过今天的学习,已经解惑了。下面就跟着我的节奏去把这个拿下吧
    2018-07-07
  • Mysql数据库之索引优化

    Mysql数据库之索引优化

    MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。本文给大家介绍mysql数据库之索引优化,感兴趣的朋友一起学习吧
    2016-03-03
  • MySql下关于时间范围的between查询方式

    MySql下关于时间范围的between查询方式

    这篇文章主要介绍了MySql下关于时间范围的between查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • MySQL存储表情时报错:java.sql.SQLException: Incorrect string value:‘\xF0\x9F\x92\xA9\x0D\x0A...’的解决方法

    MySQL存储表情时报错:java.sql.SQLException: Incorrect string value:‘

    这篇文章主要给大家介绍了关于MySQL存储表情时报错:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\xA9\x0D\x0A...'的解决方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2018-04-04

最新评论