您的位置:首页 > 职场人生

一道关于索引的使用和key_len的计算的面试题

2017-10-15 16:09 330 查看
题目如下:

mysql有一个联合索引KEY(a,b,c),a为tinyint类型(长度为1),b为mediumint类型(长度为3),c为int类型(长度4)。写出条件where a=1 and c=1所使用到的此索引的长度。

我的思路是这个联合索引(复合索引),只用到了最左的a.所以长度应该是1.当然长度也可能是8(1+3+4),即任何情况下,用到了索引,key_len的长度都是这个索引的整体长度.

测试:

创建一个表

create table abc
(
id int primary key auto_increment,
a TINYINT,
b MEDIUMINT,
c  int
)


插入数据

insert into abc(a,b,c) VALUES(1,1,1);


添加索引

alter table abc add key abc(a,b,c);


测试

select id from abc where a = 1 and c = 1;  # 测试结果key_len = 2


执行计划居然显示key_len是2. 我一下就瞎了!!!

继续测试

select id from abc where a = 1 and b = 1;  #  测试结果key_len = 6


select id from abc where a = 1 and b = 1 and c = 1;  #  测试结果key_len = 11


测试结果分别是2,6,11 而我的想法是1,4,8(分别为1,1+3,1+3+4).

百思不得骑姐啊.

就查资料,找到了下面这篇文章

MySQL key_len 大小的计算

看到了下面这段话

变长字段需要额外的2个字节,固定长度字段不需要额外的字节。而null都需要1个字节的额外空间,所以索引字段最好不要为NULL,因为NULL让统计更加复杂,并且需要额外一个字节的存储空间。

然后参照自己的结果,得到了证实.2,6,11分别是(1+1,4+2,8+3).因为abc三个字段我都没有设置not null.

继续测试.

创建表,插入数据,添加索引

create table abcnotnull
(
id int primary key auto_increment,
a TINYINT not null,
b MEDIUMINT not NULL,
c  int  not NULL
)
insert into abcnotnull(a,b,c) VALUES(1,1,1);
alter table abcnotnull add key abc(a,b,c);


测试

select id from abcnotnull where a = 1 and c = 1;  # 测试结果key_len = 1
select id from abcnotnull where a = 1 and b = 1;   # 测试结果key_len = 4
select id from abcnotnull where a = 1 and b = 1 and c = 1;    # 测试结果key_len = 8


再次证实了 null都需要1个字节的额外空间.

需要注意的是varchar(10)和char(10)指的是10个字符,他们的字节长度和具体的字符编码有关.如utf-8一个字符就是三个字符.key_len的长度是以字节为单位的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql 索引