使用explain分析sql性能时,里面有一列key_len

G7OUfS.jpg

该列显示了MySQL使用的索引的字节数。对于多列组成的联合索引,如果MySQL只是使用了联合索引里的某些列,通过key_value的值可以算出是哪些列。

但是key_value的值是怎样计算得到的?上图中字段mobile的类型是char(11)key_value的值是33

查阅了资料,总结下部分计算规则。

  • int - 4个字节,bigint - 8个字节
  • char, varchar - 需要根据使用字符集来判断,GBK使用2个字节编码一个字符,UTF8使用3个字节编码一个字符
  • 对于varchar,需要额外的2个字节来保存长度信息。
  • 可以是null的字段,需要额外的一个字节来保存NULL。

下面是一些具体的例子

CREATE TABLE `shu_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `name` char(11) NOT NULL DEFAULT '' COMMENT '用户名',
  `mobile` char(11) NOT NULL DEFAULT '' COMMENT '手机号码',
  `create_time` int(11) DEFAULT 0 COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `mobile` (`mobile`),
  KEY `create_time` (`create_time`),
  KEY `name_create_time` (`name`, `create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'
  • 主键id是int类型,而且not null,所以key_len=4
explain select * from shu_users where id = 2;

GHl3GV.jpg

  • 字段create_time是int类型,同时允许值为null,key_len=4+1=5
explain select * from shu_users where create_time = 1401262736;

GHlsxO.jpg

  • 字段mobile是char(11)类型,不允许值为null, 表的字符集是utf8key_len=11*3=33
explain select * from shu_users where mobile = "13333333333";

GHl5JP.jpg

  • 如果将mobile字段修改为varchar(11)类型,且允许值为null,表的字符集还是utf8key_len=11*3+2+1=36
explain select * from shu_users where mobile = "13333333333";

GH1KyD.jpg

  • 对应联合索引name_create_time, 下面的sql只用到索引的第一列name,name字段的类型是varchar(11)类型,不允许值为null,key_value=11*3+2=35
explain select * from shu_users where name like "李%";

GH3ruD.jpg

Last modification:April 11th, 2020 at 01:16 pm
如果觉得我的文章对你有用,请尽情赞赏 🐶