ChatGPT3.5使用体验( 五 )


覆盖索引
索引确实能够提高查询的效率,但二级索引会有某些情况会存在二次查询也就是回表的问题,这种情况合理的使用覆盖索引,能够提高索引的效率,减少回表的查询 。
覆盖索引将需要查询的值建立联合索引,这样索引中就能包含查询的值,这样查询如果只查询 索引中的值和主键值 就不用进行二次查询了,因为当前索引中的信息已经能够满足当前查询值的请求 。
回表查询
回表查询可以理解为二级索引的查询,先定位主键然后,在定位行记录的过程,它的性能相较于一次就定位到数据的查询,效率更低 。
一般建立的索引,不管是单列索引还是联合索引,一个索引就对应一课独立的 B+ 树,索引 B+ 树的节点仅仅包含了索引中几个常见的字段以及主键值 。
如果根据索引查找到了需要的数据,如果查询的值仅仅是索引中的值和主键值,那么这时候是不需要进行二次查询的,也就是回表查询,因为当前索引中的信息已经能够满足当前查询值的请求,如果查询的字段是还有其他的字段,这种情况,索引中的值不能覆盖了,就需要二次查询了,通过主键值去聚簇索引中找到对应的行,然后返回 。
所以说非聚簇索引一定会回表查询吗,答案是否定的,这涉及到查询语句所要求的字段是否全部命中了索引,如果是,那么就不需要回表查询 。
使用
参见文章MySQL学习----查看一条sql 的性能
索引优化 索引下推
索引下推(index),是.6开始支持的一种根据索引进行查询的优化方式 。
索引下推,主要是用来通过减少回表的次数,提高查询的性能 。
索引条件下推 (ICP) 是针对 MySQL 使用索引从表中检索行的情况的优化 。如果没有 ICP,存储引擎会遍历索引以定位基表中的行,并将它们返回给 MySQL 服务器,MySQL 服务器会评估这些 WHERE 行的条件 。启用 ICP 后,如果 WHERE仅使用索引中的列可以评估部分条件,则 MySQL 服务器会推送这部分条件 WHERE 条件下降到存储引擎 。然后,存储引擎使用索引条目评估推送的索引条件,只有在满足条件时才会从表中读取行 。ICP 可以减少存储引擎必须访问基表的次数和 MySQL 服务器必须访问存储引擎的次数 。
简单点讲就是在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数 。
举个栗子
假设有一个表包含了一个人的住址信息,然后在其上建立了一个索引:
INDEX ( age ,)
然后我们执行以下查询:
SELECT * FROM peopleWHERE age = 24AND name LIKE '%小%';
因为 name 使用了通配符开头的 like,就需要全表扫描了 。所以上面的联合索引,只命中了索引 age 。
在没有索引下推之前:MySQL 就首先通过 age 索引定位查询的数据,然后命中一部分数据,之后 name 会在这些数据中进行全数据的扫描,首先通过 id 回表查询到对应的数据,然后在对比字段值 。
有了索引下推:可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数 。
没有添加索引下推
索引下推优化之后
这样可以看到经过索引下推的优化,原本需要进行 4 次的回表查询,优化之后只需要 2 次的回表查询了 。
ICP 的一些使用限制:
1、当 SQL 需要全表访问时,ICP 的优化策略可用于range, ref, , 类型的访问数据方法 ;
2、支持和表;
3、ICP 只能用于二级索引,不能用于主索引;
4、并非全部 WHERE 条件都可以用 ICP 筛选,如果 WHERE 条件的字段不在索引列中,还是要读取整表的记录到端做 WHERE 过滤;