一、定义
如果一个索引包含(或覆盖)所有查询的字段值,我们称之为覆盖索引。
索引是一种查找数据的高效方式,但MySQL也可以使用索引直接获取列的数据,这样就不用读取数据的行。
二、覆盖索引优势
- 减少数据访问量和减少响应时间
索引条目通常小于数据行大小,只读取索引,极大减少数据访问量。对缓存的负载非常重要,响应时间大部分花在数据拷贝。
覆盖索引对应I/O密集型应用也有帮助,因索引比数据更小,更容易全部放到内存中(MyISAM压缩索引更小)。 - 减少I/O
索引按照列值顺序存储,索引对于I/O密集型的范围查询会比从磁盘随机读取每一行数据的I/O少很多。 - 减少系统调用和降低开销
一些存储引擎如MyISAM在内存中只缓存索引,数据则依赖当前操作系统缓存,因此要访问数据需要一次系统调用。这可能导致严重的性能问题,尤其是那些系统调用占了数据访问中的最大开销的场景。 - InnoDB避免二次查询
由于InnoDB的聚簇索引,覆盖索引对InnoDB特别有用。InnoDB的二级索引在叶子节点保存了行的主键值,所以如果二级主键查询能够覆盖索引,则可以避免对主键索引的二次查找。
三、使用索引条件及Extra
MySQL只能使用B-Tree索引做覆盖索引,覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引等都不存储索引列的值。不同存储引擎实现覆盖索引方式也不同。
当发起一个被覆盖索引的查询时,在EXPLAIN的Extra列可以看到Using index的信息。
四、覆盖索引失效及解决方案
- 失效1:索引覆盖WHERE条件中字段,但不是整个查询的字段
延迟关联
利用InnoDB的二级索引 - 失效2:LIKE模糊查询
原因:MySQL5.5及之前版本只允许在索引中做简单比较操作限制(=、!=及小于),这是底层存储引擎API限制。MySQL5.6之后已支持,由于ICP这个特性改善了查询执行方式。
解决方案:升级MySQL到5.7;延迟关联;最左前缀匹配。
—- END —-