MySQL explain中key_len的计算

本文深入解析MySQL中Key_len参数的计算方法,详细说明了不同数据类型、字符集及索引字段属性如何影响Key_len值,通过实例展示了Key_len在联合索引中的应用,帮助读者理解并优化SQL查询。

key_len表示索引使用的字节数,根据这个值可以判断索引的使用情况,特别是在组合索引的时候,判断该索引有多少部分被使用到非常重要。
在计算key_len时,下面是一些需要考虑的点:

  • 索引字段的附加信息:可以分为变长和定长数据类型讨论,当索引字段为定长数据类型时,如char,int,datetime,需要有是否为空的标记,这个标记占用1个字节(对于not null的字段来说,则不需要这1字节);对于变长数据类型,比如varchar,除了是否为空的标记外,还需要有长度信息,需要占用两个字节。

  • 对于,char、varchar、blob、text等字符集来说,key len的长度还和字符集有关,latin1一个字符占用1个字节,gbk一个字符占用2个字节,utf8一个字符占用3个字节。

综上,下面来看一些例子:

列类型KEY_LEN备注
id intkey_len = 4+1int为4bytes,允许为NULL,加1byte
id bigint not nullkey_len=8bigint为8bytes
user char(30) utf8key_len=30*3+1utf8每个字符为3bytes,允许为NULL,加1byte
user varchar(30) not null utf8key_len=30*3+2utf8每个字符为3bytes,变长数据类型,加2bytes
user varchar(30) utf8key_len=30*3+2+1utf8每个字符为3bytes,允许为NULL,加1byte,变长数据类型,加2bytes
detail text(10) utf8key_len=30*3+2+1TEXT截取部分,被视为动态列类型。

备注:key_len只指示了where中用于条件过滤时被选中的索引列,是不包含order by/group by这一部分被选中的索引列的。
例如,有个联合索引idx(c1,c2,c3),3列均是int not null,那么下面的SQL执行计划中,key_len的值是8而不是12:

select ... from tb where c1=? and c2=? order by c1;

参考文章:
mysql explain 中key_len的计算
解读EXPLAIN执行计划中的key_len

### EXPLAIN 中 `key_len` 的含义 在 SQL 查询优化过程中,`EXPLAIN` 是一种非常重要的工具,用于显示 MySQL 如何处理查询语句以及如何决定使用哪些索引。其中,`key_len` 表示 MySQL 计划使用的索引部分的最大长度(单位为字节)。这个值可以提供关于索引列的数据类型及其效率的重要线索。 #### 1. **`key_len` 的计算方式** `key_len` 值取决于所选索引的字段数据类型和大小。如果索引由多个列组成,则 `key_len` 将反映这些列组合后的总长度[^1]。例如: - 如果索引是一个整数类型的列 (`INT`),那么它的长度通常是 4 字节。 - 对于字符串类型 (如 `VARCHAR(20)` 或 `CHAR(10)`),其长度会根据字符集的不同而变化。UTF8 编码下的单个字符可能占用多达 3 字节的空间,因此一个 `VARCHAR(20)` 列可能会被分配最多 60 字节作为键长。 当多列构成复合索引时,`key_len` 可能表示的是参与匹配的部分列的累积长度。这表明只有某些前缀列被实际利用到了查询过滤中。 #### 2. **影响因素** 以下是几个会影响 `key_len` 数值的因素: - 数据库中的编码设置决定了每种数据类型的存储空间需求; - 是否存在 NULL 值标志位——即使某列为 NOT NULL 定义,也可能因其他原因额外增加少量开销来标记该位置是否存在有效数据; - 当遇到范围查找或者模糊搜索(`LIKE '%abc%'`)等情况时,通常不会完全依赖整个索引来完成筛选工作,而是仅限于前面若干固定模式部分,从而导致较小的关键字长度报告出来[^2]。 #### 3. **解读意义** 通过观察 `key_len` 的具体数值,开发者可以获得如下洞察: - 较短的 `key_len` 很可能是由于选择了较窄的有效索引子集所致;这意味着虽然指定了较大的联合索引,但实际上只用了很少一部分来进行快速定位记录的操作。 - 高效的设计应该尽量让每次访问都能充分利用完整的索引结构而不是仅仅依靠开头几项属性来做判断依据。这样不仅可以减少不必要的磁盘 I/O 请求次数还能提升整体性能表现。 下面给出一段 Python 脚本用来模拟展示不同条件下 key length 的差异情况: ```python import pymysql.cursors connection = pymysql.connect(host='localhost', user='root', password='', database='test_db') try: with connection.cursor() as cursor: sql = "EXPLAIN SELECT * FROM users WHERE username LIKE %s" cursor.execute(sql, ('a%',)) result = cursor.fetchall() finally: connection.close() print(result) ``` 此脚本连接至本地数据库并运行带有参数化占位符 `%s` 的查询计划请求。它将返回有关当前表上基于特定条件执行扫描的信息列表之一即包含我们关心的那个字段解释说明。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值