mysql覆盖索引详解

覆盖索引的定义:mysql

若是一个索引包含(或覆盖)全部须要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。sql


只扫描索引而无需回表的优势:
    1.索引条目一般远小于数据行大小,只须要读取索引,则mysql会极大地减小数据访问量。
    2.由于索引是按照列值顺序存储的,因此对于IO密集的范围查找会比随机从磁盘读取每一行数据的IO少不少。
    3.一些存储引擎如myisam在内存中只缓存索引,数据则依赖于操做系统来缓存,所以要访问数据须要一次系统调用
    4.innodb的聚簇索引,覆盖索引对innodb表特别有用。(innodb的二级索引在叶子节点中保存了行的主键值,因此若是二级主键可以覆盖查询,则能够避免对主键索引的二次查询)
缓存

覆盖索引必需要存储索引列的值,而哈希索引、空间索引和全文索引不存储索引列的值,因此mysql只能用B-tree索引作覆盖索引。
服务器

当发起一个索引覆盖查询时,在explain的extra列能够看到using index的信息
优化

覆盖索引的坑:mysql查询优化器会在执行查询前判断是否有一个索引能进行覆盖,假设索引覆盖了where条件中的字段,但不是整个查询涉及的字段,mysql5.5和以前的版本也会回表获取数据行,尽管并不须要这一行且最终会被过滤掉。
spa

如上图则没法使用覆盖查询,缘由:
    1.没有任何索引可以覆盖这个索引。由于查询从表中选择了全部的列,而没有任何索引覆盖了全部的列。
操作系统

    2.mysql不能在索引中执行LIke操做。mysql能在索引中作最左前缀匹配的like比较,可是若是是通配符开头的like查询,存储引擎就没法作比较匹配。这种状况下mysql只能提取数据行的值而不是索引值来作比较设计

优化后SQL:添加索引(artist,title,prod_id),使用了延迟关联(延迟了对列的访问)

说明:在查询的第一阶段可使用覆盖索引,在from子句中的子查询找到匹配的prod_id,而后根据prod_id值在外层查询匹配获取须要的全部值。3d

5.5时API设计不容许mysql将过滤条件传到存储引擎层(是把数据从存储引擎拉到服务器层,在根据条件过滤),5.6以后因为ICP这个特性改善了查询执行方式blog

相关文章
相关标签/搜索