重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍了MySQL执行计划里面的key_len有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
成都创新互联公司自成立以来,一直致力于为企业提供从网站策划、网站设计、网站设计制作、网站设计、电子商务、网站推广、网站优化到为企业提供个性化软件开发等基于互联网的全面整合营销服务。公司拥有丰富的网站建设和互联网应用系统开发管理经验、成熟的应用系统解决方案、优秀的网站开发工程师团队及专业的网站设计师团队。
以前看MySQL的执行计划,感觉内容有些简陋,平时分析主要就是看是否全表扫描,索引使用是否合理等。基本上也能分析出很多问题来,但是显然有时候会有些疑惑,那就是对于复合索引,多列值的情况下,到底启用了那些索引列,这个时候索引的使用情况就很值得琢磨琢磨了,我们得根据执行计划里面的key_len做一个重要的参考。
我们做一个简单的测试来说明。
CREATE TABLE `department` (
`DepartmentID` int(11) DEFAULT NULL,
`DepartmentName` varchar(20) DEFAULT NULL,
KEY `IND_D` (`DepartmentID`),
KEY `IND_DN` (`DepartmentName`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
运行语句为:explain select count(*)from department\G
对于这个语句,key_len到底是多少呢?
mysql> explain select count(*)from department\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: department
type: index
possible_keys: NULL
key: IND_D
key_len: 5
ref: NULL
rows: 1
Extra: Using index
1 row in set (0.00 sec)
在这个例子里面,possible_keys,key,Extra你看了可能有些晕,我们看看key_len的值为5,这个值是怎么算出来的呢,首先表有两个字段,第一个字段的类型为数值,int的长度为4,因为字段可为null,所以需要一个字节来存储,这样下来就是4+1=5了。由此我们可以看到这个语句是启用了索引ind_d.
那我们举一反三,把语句修改一下,看看key_len的变化。
mysql> explain select departmentName from department b where departmentName='TEST'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ref
possible_keys: IND_DN
key: IND_DN
key_len: 43
ref: const
rows: 1
Extra: Using where; Using index
1 row in set (0.09 sec)
从上面可以看到,key_len为43,这个值是怎么算出来的呢,我们来掰扯一下,字段2为字符型,长度20,因为是GBK字符集,所以需要乘以2,因为允许字段为NULL,则需要一个字节,对于变长的类型(在此就是VARCHAR),key_len还要加2字节。这样下来就是20*2+1+2=43
到了这里仅仅是个开始,我们需要看看略微复杂的情况,就需要复合索引了。我们就换一个表test_keylen2
create table test_keylen2 (c1 int not null,c2 int not null,c3 int not null);
alter table test_keylen2 add key idx1(c1, c2, c3);
下面的语句就很实际了,
explain SELECT *from test_keylen2 WHERE c1=1 AND c2=1 ORDER BY c1\G
这个语句中,keylen到底是应该为4或者8还是12呢? 我们就需要验证一下了。
mysql> explain SELECT *from test_keylen2 WHERE c1=1 AND c2=1 ORDER BY c1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_keylen2
type: ref
possible_keys: idx1
key: idx1
key_len: 8
ref: const,const
rows: 1
Extra: Using index
1 row in set (0.07 sec)
显然key_len只计算了where中涉及的列,因为是数值类型,所以就是4+4=8
那下面的这个语句呢。
explain SELECT *from test_keylen2 WHERE c1>=1 and c2=2 \G
我们添加一个范围,看看这个该如何拆分。
mysql> explain SELECT *from test_keylen2 WHERE c1>=1 and c2=2 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_keylen2
type: index
possible_keys: idx1
key: idx1
key_len: 12
ref: NULL
rows: 1
Extra: Using where; Using index
1 row in set (0.07 sec)
在这里就不只是计算where中的列了,而是因为>1的条件直接选择了3个列来计算。
对于date类型的处理,有一个很细小的差别。我们再换一个表,含有事件类型的字段,
CREATE TABLE `tmp_users` (
`id` int(11) NOT NULL
AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`l_date` datetime NOT NULL,
`data` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ind_uidldate` (`uid`,`l_date`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
下面的语句key_len该如何计算呢。
explain select * from tmp_users where uid = 9527 and l_date >= '2012-12-10 10:13:17'\G
这一点出乎我的意料,按照datetime的印象是8个字节,所以应该是8+4=12,但是这里却偏偏是9,这个数字怎么计算的。
id: 1
select_type: SIMPLE
table: tmp_users
type: range
possible_keys: ind_uidldate
key: ind_uidldate
key_len: 9
ref: NULL
rows: 1
Extra: Using index condition
1 row in set (0.07 sec)
这里就涉及到一个技术细节,是在MySQL 5.6中的datetime的存储差别。在5.6.4以前是8个字节,之后是5个字节
所以按照这个算法就是4+5=9
感谢你能够认真阅读完这篇文章,希望小编分享的“MySQL执行计划里面的key_len有什么用”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!