大佬们,最近复习 mysql 索引,有个问题求解答。 看的图灵视频,有涉及到 explain 的 key_len 字段,用来判断查询语句中用了某个组合索引的哪些列。 视频里有个结论比较疑惑,如下图: ![]()
不太明白红色框的两种情况。
本地测试 SQL:
CREATE TABLE `foo` ( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键', `a` varchar(7) NOT NULL DEFAULT '', `b` int(11) NOT NULL DEFAULT '1', `c` varchar(3) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_common_01` (`a`,`b`,`c`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; EXPLAIN SELECT a,b,c FROM foo where a = 'a1' and b > 1 and c = 'cc' -- key_len 计算: -- a 列 7*3+2 = 23 -- b 列 4 -- c 列 3*3+2 = 11 -- 如用了 a,b 列,则 key_len=27 -- 如用了 a,b,c 列,则 key_len=38 CREATE TABLE `bar` ( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键', `a` varchar(7) NOT NULL DEFAULT '', `b` varchar(10) NOT NULL DEFAULT '', `c` varchar(3) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_01` (`a`,`b`,`c`) USING BTREE COMMENT 'abc 索引' ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; EXPLAIN SELECT a,b,c FROM bar where a = 'a1' and b like 'x%' and c = 'cc' -- key_ln 计算: -- a 列 7*3+2 = 23 -- b 列 10*3+2 = 32 -- c 列 3*3+2 = 11 -- 如用了 a,b 列,则 key_len=58 -- 如用了 a,b,c 列,则 key_len=66 计算背景:字符集为 utf8
varchar 列不允许 null ,key_len=长度 x3+2
如列 a 定义:varchar(12) not null default '', a 列的 key_len=12*3+2=38
int 列不允许 null ,key_len=4
如列 b 定义:int(11) not null default '1', b 列的 key_len=4
第一种情况比较好理解,第二个情况where a='xx' and like 'x%' and c='xx'为什么能用到 c 列呢?(本地测试 key_len 计算后确实用到了 c 列)
