一、索引长度:在SQL执行计划中,key_len 表示索引长度,经常用于判断复合索引是否被完全使用。

注:在utf8编码方式下,一个字符占3个字节;utf8mb4一个字符占4个字节;gbk中一个字符占2个字节;latin中一个字符占1个字节。索引长度可以指定,不指定的情况下会按照规则使用默认的长度。

1、默认索引长度定义:在没有指定索引长度的情况下,如果索引字段不为空且长度不可变,索引长度等于该字段的长度;可以为null,mysql会用1个字节标识;长度可变,MySQL会使用2个字节标识。以utf8编码为例

(1)如果索引字段不为空且长度不可变,索引长度等于该字段的长度;

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

随便插入几条数据:

   

mysql索引三层的数据量 mysql索引长度是多少_SQL

 

 索引查询: key_len = 60,索引段name的长度是20个字符,key_len = 20*3 = 60。

   

mysql索引三层的数据量 mysql索引长度是多少_字段_02

(2)如果索引字段不为空,长度可变:改成varchar:

   

mysql索引三层的数据量 mysql索引长度是多少_mysql索引三层的数据量_03

查询:key_len = 20*3 +2= 62

mysql索引三层的数据量 mysql索引长度是多少_mysql索引三层的数据量_04

(3)如果索引字段可以为空,长度不可变:

    

mysql索引三层的数据量 mysql索引长度是多少_SQL_05

  查询:key_len = 20*3 +1= 61

  

mysql索引三层的数据量 mysql索引长度是多少_SQL_06

(4)以此类推,字段既可以为空长度也可变,索引长度+2+1:

   

mysql索引三层的数据量 mysql索引长度是多少_主键_07

查询:

  

mysql索引三层的数据量 mysql索引长度是多少_字段_08

(5)复合索引:索引列长度之和

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `address` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name_address` (`name`,`address`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

  

mysql索引三层的数据量 mysql索引长度是多少_mysql索引三层的数据量_09

 

 key_len长度为63,说明只用到了复合索引的前半部分;

mysql索引三层的数据量 mysql索引长度是多少_mysql索引三层的数据量_10

 key_len长度为126,说明该SQL查询语句用了整个复合索引。

 综上,key_len 表示索引长度,经常用于判断复合索引是否被完全使用。

2、指定索引长度:

CREATE INDEX index_name ON table_name column_name(length);

 如对于表

mysql索引三层的数据量 mysql索引长度是多少_字段_11

 设置索引长度:

ALTER TABLE test ADD INDEX index_name_address (`name`(10),`address`(10));

 

mysql索引三层的数据量 mysql索引长度是多少_字段_12

 key_len = 10*3+2+1+10*3+2+1=66。

二、索引区分度:区分度百分比 = select count(distinct left(索引字段,索引长度))/count(1) from table。区分度越高,查询越快,如主键索引,主键是唯一的,主键索引的区分度就是1。区分度低的索引原则上已失去意义,没有明显的查询效率,而且添加了索引每次查询会先走索引树,再回表查询,增加了额外的io消耗,就不如直接查询原表来的效率高

三、总结:索引长度和区分度是相互矛盾的,索引长度太短,那么区分度就很低,把索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点。

举个例子:(张,张三,张三哥),如果索引长度取1的话,那么每一行的索引都是 张 这个字,完全没有区分度,无法排序,结果这样三行完全是随机排的,因为索引都一样;如果长度取2,那么排序的时候至少前两个是排对了的,如果取3,区分度达到100%,排序完全正确;但是并不是索引越长越好,比如 (张,李,王) 和 (张三啦啦啦,张三呵呵呵,张三呼呼呼);前者在内存中排序占得空间少,排序也快,后者明显更慢更占内存,在大数据应用中这一点点影响都是很大的。