索引覆盖是指 如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回到磁盘查找数据。这种查询速度非常快,成为索引覆盖
例如表user
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`desc` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_name` (`id`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
当 select name from user where id>3;时,因为name即为索引的一部分所有直接在索引上就可以查到数据
而当 select desc form user where id>3时,则需要回行到磁盘读取数据
经典案例
create table `user`(
`id` int(11) auto_increment,
`name` varchar(20),
`desc` varchar(3000),
`extra` varchar(3000),
primary key (`id`),
key id_name(`id`,`name`)
)
疑问:select id from user order by id为什么非常慢,
而select id from user order by id,name 反而很快,
两个语句都有索引覆盖,正常应该都很快
解析:
1.这个表用的引擎是innodb,因为innodb主键索引是聚簇索引,主键索引上存放了行数据,而该表中有几个大数据字段,主键索引id需要在磁盘跨n多块,导致查询很慢。而id,name联合索引为次索引,指向主键的引用,不存放行数据,所以查询较快。
2.如果是myisam引擎则两条语句的查询数据应该差不多,因为myisam引擎是非聚餐索引,索引只存放行数据的位置。
3.即使该表的引擎为innodb,如果没有那几个varchar(3000)大字段,两条查询语句效率也是差不多的
网友评论