mysql覆盖索引理解

覆盖索引概念:

  MySQL可以利用索引返回SELECT 列表中的字段。而不必根据索引再次读取数据文件。包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index)。也就是平时所说的不需要回表操作。
判断标准:
 在查询前面使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL查询优化器在执行查询前会决定是否有索引覆盖查询。
 
注意:覆盖索引也并不适用于任意的索引类型,索引必须存储列的值。Hash 和full-text索引不存储值,因此MySQL只能使用B-TREE。并且不同的存储引擎实现覆盖索引都是不同的。并不是所有的存储引擎都支持它们。如果要使用覆盖索引。一定要注意SELECT 列表值取出需要的列。不可以是SELECT * ,因为如果将所有字段一起做索引会导致索引文件过大。查询性能下降。不能为了利用覆盖索引而这么做。
 
InnoDB中,覆盖索引查询时除了除了索引本身的包含的列,还可以使用其默认的聚集索引列 。
Innodb的索引是B+Tree数据结构,这个跟MyISAM也是一样的,不同的是Innodb的Primary Index叶子节点直接存储了Row记录数据,而Secondary Index存储了PK值。而MyISAM索引的叶子节点存储的是记录的ID,即RowID。
下图是Innodb的索引示意图:
 

mysql覆盖索引理解
 
 
1)如果一个索引值跟Key值不是一一对应的关系,那么叶子节点存储的可能是一个映射地址,指向一个对应了多个Pk值的映射表;
有些数据库是如此操作的,具体Innodb是否如此,我还不太确认;
2)对于组合主键,其实就是把多个字段值组合起来作为Primary Key,结构跟Primary Key Index是一样的;
3)由于所有非Primary key index都引用了Primary Key所以对Primary Key的变更会导致所以索引都要重建;
4)Innodb默认的pagesize是16K,通过编译源码可以指定为64K,pagesize就是B+Tree上一个节点的容量,pagesize越大key值越小,单个结点能存储的entry就越多。当索引树每分裂出多一层,索引的Size也会随之发生跳跃性的变化。
 
参考资料:
 
如果你对数据库设计的细节非常的感兴趣,我强力建议你可以认真看看这本书《Fundamentals of Database Systems》,
中文译名是《数据库系统基础》,中国电力出版社有出。现在好像已经是第五版了。

相关推荐