MySQL常用explain命令查看SQL的执行计划,如:
其中key_len列表示SQL使用的索引长度,单位为字节,通常在不损失精确性的情况下,长度越短越好。
一般可以根据表定义大概计算出索引的最大可能长度,可用于判断联合索引的实际使用字段情况。
一、索引长度计算规则1、一般地,key_len等于索引列类型字节长度,例如tinyint类型为1字节,int类型为4字节,bigint为8字节。
2、如果是字符串类型,还需要同时考虑字符集因素(latin1为1字节/gbk为2字节/utf8为字节/utf8mb4为4字节),例如:CHAR(0)UTF8,则key_len至少是90字节。
、如果是日期时间型,还需要考虑精度值,在MySQL5.6.4版本之后,各个日期时间类型需要的存储空间如下:
其中小数秒是什么意思呢?
在MySQL5.6.4这个版本之后,TIME、DATETIME、TIMESTAMP这几种类型添加了对毫秒、微秒的支持。由于毫秒、微秒都不到1秒,所以也被称为小数秒,MySQL最多支持6位小数秒的精度,前三位标识毫秒,后三位标识微秒。
以datetime为例,一般情况下时间格式为YYYY-MM-DDHH:MM:SS,为了让我们的datetime类型支持小数秒,可以这么写:
dateime(小数秒位数),其中小数秒位数可以在0、1、2、、4、5、6中选择。
比如DATETIME(0)表示精确到秒,DATETIME()表示精确到毫秒,DATETIME(5)表示精确到10微秒。如果你在选择TIME、DATETIME、TIMESTAMP这几种类型的时候添加了对小数秒的支持,那么所需的存储空间需要相应的扩大,保留不同的小数秒位数,那么增加的存储空间大小也不同,如下表:
所以,计算索引长度时,datetime类型下,如果不使用小数秒,则只占用5个字节长度,datetime相当于是datetime(0),仅占用5字节空间,而datetime(1)或datetime(2)占用6字节、datetime()或datetime(4)占用7字节、datetime(5)或datetime(6)占用8字节。
4、若该列类型定义时允许NULL,还需要再加1字节。
5、若该列类型为变长类型,例如VARCHAR(TEXT/BLOB不允许整列创建索引,如果创建部分索引也被视为动态列类型),还需要再加2字节来存储该变长列的实际长度。
首先,看看官方文档对varchar类型存储空间长度的说法。
即MySQL需要1~2个字节来表示varchar字符串的长度。具体来说,如果字符串占用的字节数在0~之间,需1个字节来表示,如果大于个字节,则需2个字节来表示。
但在计算索引长度的时候,统一加2字节存储该变长列的实际长度,与是否超过字节无关。
测试如下:
二、案例索引长度计算如下:
(varchar50*4+2变长+1空值)+(varchar10*4+2变长)+(datetime()5+2)+(varchar6*4+2变长)=20+42+7+26=
由此可看出idx_test的所有字段都走了索引。
三、总结MySQL在执行计划中输出key_len列主要是为了让我们区分某个使用联合索引的查询具体用了几个索引列。
因为联合索引有最左前缀的特性,如果联合索引能全部使用上,则是联合索引字段的索引长度之和,这样就可以用来判定联合索引是部分使用,还是全部使用。