Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL EXPLAIN使用

MySQL EXPLAIN中key_len使用的终极指南

作者:努力的小郑

本文将深入解析MySQL执行计划中最关键的指标之一,EXPLAIN中key_len的使用,可以帮助大家快速定位索引优化点,从而提升查询性能

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

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

EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 'shipped';

-- 输出示例(修正对齐问题):
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table  | type | possible_keys | key     | key_len | ref         | rows | Extra |
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------+
|  1 | SIMPLE      | orders | ref  | idx_composite | idx_composite | 86      | const,const |    1 | NULL  |
+----+-------------+--------+------+---------------+---------+---------+-------------+------+-------+

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

1. 基础计算规则

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

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)
DECIMAL(10,2)整数4字节+小数2字节+1字节-67

核心要点

三、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)

-- 方案2:ENUM替代(有限值场景)
ALTER TABLE orders 
  MODIFY status ENUM('pending','shipped','completed') NOT NULL;
-- key_len≈1-2字节

-- 方案3:压缩长文本+哈希索引
ALTER TABLE articles 
  ADD COLUMN content_hash BINARY(16) NOT NULL,
  ADD INDEX (content_hash);

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优化四原则

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

通过精准解读key_len,您将获得索引优化的"X光视力"。下次查看EXPLAIN结果时,重点关注key_len值——这个不起眼的数字可能是性能突破的关键!

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

您可能感兴趣的文章:
阅读全文