CREATE TABLE `test_users` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`USER_ID` varchar(11) DEFAULT NULL COMMENT '用户账号',
`USER_NAME` varchar(255) DEFAULT NULL COMMENT '用户名',
`AGE` int(5) DEFAULT NULL COMMENT '年龄',
`COMMENT` varchar(255) DEFAULT NULL COMMENT '简介',
PRIMARY KEY (`ID`),
UNIQUE KEY `UNIQUE_USER_ID` (`USER_ID`) USING BTREE,
KEY `idx_user_name_age` (`USER_NAME`,`AGE`)
) ENGINE=InnoDB AUTO_INCREMENT=3664300 DEFAULT CHARSET=utf8
Mysql版本:8.0.15。
这张test_users表里,id是主键索引,user_id是唯一索引,user_name和age是复合(联合)索引,comment是普通字段。
Extra值只是一个额外的信息,更多的是用来解释和说明,所以是extra。关键信息还得看key,key是最权威的答案。
using index,当是using index的时候,说明你要查询的字段是有索引在身的。此时key肯定有值的,来说明最终选择了哪个索引,而Extra是using index的意思是用来补充一句,多说一句,『这个查询的字段刚好有索引,所以是using index(只用到了索引就查到了答案,不需要再回表二次查询)』
如下几个查询:
第一类:不包含where条件的查询:
explain select id from test_users limit 1; // 要查询的是id,主键索引
explain select user_id from test_users limit 1; // 要查询的是user_id,唯一索引
explain select user_name,age from test_users limit 1; // 要查询的是user_name和age,复合索引
explain select age,user_name from test_users limit 1; // 要查询的是age和user_name,复合索引
explain select age from test_users limit 1; // 要查询的是age,复合索引
explain select user_name from test_users limit 1; // 要查询的是user_name,复合索引
以上这些都会用有Using index,using index的意思就是,只需要使用索引就可以查到所需的字段。我们查的是那些字段,刚好那些字段上都有索引,这就是所谓的『只需要使用索引就可以查到所需的字段』。其他情况都没有using index在extra字段。
第二类:包含where条件的查询:
非复合索引的情况:
1、当select的field等于where的field且该field身上有索引且非复合索引的时候,Key会是该索引,并且Extra会是using index;
例如:explain select user_id from test_users where user_id="13"; // user_id唯一索引
2、当select的field1为主键索引,where的field2身上有索引且非复合索引的时候,Key会是该索引,并且Extra会是using index;
例如:explain select id from test_users where user_id="3"; // user_id唯一索引
3、当where的field2身上没有索引的时候,Key会是null,并且Extra会是using where;
例如:explain select user_id from test_users where comment="3";
explain select id from test_users where comment="3";
复合索引的情况:
1、当select的field等于where的field且该field身上有索引且是复合索引的时候,Key会是该索引,并且Extra会是using index;
例如:
explain select user_name, age from test_users where user_name="13" and age=3; // user_name和age是复合索引
explain select user_name, age from test_users where age=3 and user_name="13"; // user_name和age是复合索引
与where中field的顺序无关
2、当select的field为主键时,where的field顺序不定但个数等于复合索引的个数的时候,Key会是该索引,并且Extra会是using index;
例如:
explain select id from test_users where age=3 and user_name="13"; // user_name和age是复合索引
explain select id from test_users where user_name="13" and age=3; // user_name和age是复合索引
2、当select的field为主键时,where的field的个数不等于复合索引的个数的时候;
复合索引的顺序是(user_name, age),所以情况会不同:
例如:
explain select id from test_users where user_name="13" ; // Key会是该索引,并且Extra会是using index;
explain select id from test_users where age=13 ; // Key会是该索引,但Extra会是using where,且全表扫描;
3、当select的field为非主键且非复合索引字段,where的field为按复合索引顺序且个数可以不等于复合索引的个数时,Key会是该索引,并且Extra会为null;
例如:explain select comment from test_users where user_name="13" ; // comment字段无索引
explain select user_id from test_users where user_name="13" and age=3; // user_id字段为唯一索引
4、当select的field为非主键且非复合索引字段,where的field不是按复合索引顺序且个数不等于复合索引的个数时,Key会是null,并且Extra会为using where;
例如:explain select comment from test_users where age=3 ; // comment无索引,age有复合索引但不是按索引顺序查的
explain select user_id from test_users where age=3 ; // user_id有索引,age有复合索引但不是按索引顺序查的
5、当select的field为复合索引字段,where的field不是按复合索引顺序且个数不等于复合索引的个数时,Key会是该索引,并且Extra会为Using where; Using index
例如:explain select user_name from test_users where age=3 ;