Mysql的索引、回表查询及覆盖索引浅析

索引的种类

在MySql中索引分为两大类,聚集索引和普通索引;

innoDB中行记录存储在聚集索引的叶子节点上,所以innoDB中必须有且只有一个聚集索引。

innoDB普通索引的叶子节点存储的是主键值。而MyISAM的叶子节点存储的是主键值的地址(或称为行记录头指针)。

聚集索引:

1)如果表中已经创建主键paramKey,则主键就是聚集索引;

2)如果没有主键,则使用第一个NOT NULL UNIQUE的列作为聚集索引;

3)否则mysql会创建一个隐藏的Rowid,作为聚集索引。

回表查询及解决对策

数据查询,通过聚集索引查询可以定位到行数据,这种情况下,不会出现回表查询的情况。

如果使用普通索引查询其他非索引数据的话,因为普通索引无法定位行数据,所以会进行回表查询,通过聚集索引再次扫描索引树,确定行数据,然后得到想要查询的其他数据。这就是所谓的回表查询。

解决办法:覆盖索引,若果所要查询的字段被索引所覆盖,那么通过查询索引,可以获取到索引所对应的值,这样就可以避免回表查询,提高查询速度。

注意事项:

不是所有的索引都可以用作为覆盖索引,哈希索引,空间索引,全文索引等都不存储列值,无法作为覆盖索引进行使用。只有B-tree才能用作为覆盖索引。

当发起索引覆盖的查询的时候,会在执行计划中出现USING INDEX的信息。

使用覆盖索引的优点

1)因为使用索引查询时,只读取索引及索引列值,而索引的大小远小于数据行的大小,所以查询时极大地减少了数据的访问量;

2)索引的存储是按照列值顺序存储的,对于IO密集型的范围查找会比随机从磁盘读取每一行数据的IO小很多。

3)相比于其他的引擎MyISAM在内存中只缓存索引,所以,使用MyISAM索引进行查询时,会调用操作系统进行一次数据的访问。使用覆盖索引就避免了这一点。

4)因为innoDB中的二级索引在叶子节点中保存了主键值,如果二级索引能够覆盖查询,就避免了对主键的回表查询。

 

原文地址:https://www.cnblogs.com/SpaceKiller/p/12984917.html