Using where 表示使用where过滤
Using index 表示使用了覆盖索引避免了回表查询
有的博客认为 Using where 表示访问聚簇索引中的行数据 即回表。
Using where 和 Using index 同时出现时 表示既使用覆盖索引避免回表又在行数据中做回表查询?显然是不对的。
其实不必想的那么复杂 Using where 表示使用where过滤数据
Using index 表示使用覆盖索引避免回表(如果是主键索引查询则表示没有读取行数据)。
案例如下:
先给出见表语句
CREATE TABLE T(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into T(name) values('zhangsan');
insert into T(name) values('lisi');
insert into T(name) values('test');
insert into T(name) values('wangwu');
insert into T(name) values('test');
alter table T add index idx_name(name);
案例一
查询SQL性能
explain select * from T where id = 3;
explain select id from T where id = 3;
因为是根据主键查询,所以两条查询的type都是const。
select * 查询没有使用覆盖索引Using index, 又因为主键索引(唯一索引) 可以直接查询到数据(type为const) 没有Using where过滤。
select id 使用了覆盖索引避免回表 所以是Using index
案例二
explain select name from T where name = 'test';
name字段是一个普通索引,不是唯一索引 所以需要使用where过滤,显然此语句又使用到了覆盖索引避免回表 所以Extra既有Using where又有Using index。
案例三
建立一个新的表TT 和案例一案例二中T表的区别在于给name字段加上了唯一性约束
CREATE TABLE TT(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT NULL UNIQUE,
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into TT(name) values('zhangsan');
insert into TT(name) values('lisi');
insert into TT(name) values('test');
insert into TT(name) values('wangwu');
insert into TT(name) values('test');
MySQL会给唯一约束自动创建一个唯一索引
show index from TT;
这时再查看SQL语句的性能
explain select name from TT where name = 'test';
对比案例二 Extra中只有Using index, Using where消失了
因为name字段是唯一索引type是const 不需要使用到where过滤。