MySQL中到底什么是覆盖索引、索引下推?

简介: 覆盖索引指查询只需通过索引即可获取数据,无需回表,提升查询效率。索引下推则在索引遍历时提前过滤条件,减少回表次数,尤其适用于联合索引中部分字段无法使用的情况,二者均能显著降低I/O开销,提高查询性能。(238字)

覆盖索引(Covering Index)

覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。


当一条查询语句符合覆盖索引条件时,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查询索引后再返回表操作,减少I/O提高效率。


如,表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。


当我们通过SQL语句:

select key2 from covering_index_sample where key1 = 'keytest';

的时候,就可以通过覆盖索引查询,无需回表。

但是以下SQL,因为不符合最左前缀匹配,虽然是索引覆盖,但是也无法用到索引(会扫描索引树):

select key1 from covering_index_sample where key2 = 'keytest';

但是如果SQL中查询的信息不包含在联合索引中,那么就不会走索引覆盖。如:

select key2,key3 from covering_index_sample where key1 = 'keytest';


索引下推

索引下推是 MySQL 5.6引入了一种优化技术,默认开启,使用SET optimizer_switch = 'index_condition_pushdown=off';可以将其关闭。


官方文档中给的例子和解释如下:people表中(zipcode, lastname, firstname)构成一个索引

SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%'

image.gif

如果没有使用索引下推技术,则MySQL会通过zipcode='95054'从存储引擎中查询对应的数据,返回到MySQL服务端,然后MySQL服务端基于lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断数据是否符合条件。


如果使用了索引下推技术,则MYSQL首先会返回符合zipcode='95054'的索引,然后根据lastname LIKE '%etrunia%'来判断索引是否符合条件。

如果符合条件,则根据该索引来定位对应的数据,如果不符合,则直接reject掉。有了索引下推优化,可以在有like条件查询的情况下,减少回表次数。


当一条SQL使用到索引下推时,explain的执行计划中的extra字段内容为:Using index condition


也就是说,5.6版本前,先匹配到zipcode索引95054,然后拿此索引对应的主键去回表,到主键索引上找到对应的记录,再判断lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断数据是否符合条件。


那么5.6版本引入了索引下推,先匹配到zipcode索引,同时还会在索引里过滤lastname和address字段,拿着过滤完剩下的索引对应的主键id再回表查整行数据。



索引下推不止like

上面的例子中,提到了like,包括MySQL官网中也只提到了like,但是其实不止有Like。因为我认为索引下推其实是解决索引失效带来的效率低的问题的一种手段。


所以当联合索引中,某个非前导列因为索引失效而要进行扫表并回表时,就可以进行索引下推优化了。


如,有a,b联合索引,类型都是varchar,以下SQL也可以用到索引下推:

select d from t2 where a = "ni" and b = 1;

因为b字段因为类型不匹配导致索引失效了,但是通过下推优化其实是可以减少回表的次数的。

目录
相关文章
|
2月前
|
XML Java 开发者
springboot自动装配的基本原理
Spring Boot自动装配基于“约定大于配置”理念,通过@SpringBootApplication、@EnableAutoConfiguration与spring.factories机制,结合条件注解实现智能Bean加载。它根据依赖自动配置组件,大幅简化开发。其核心是AutoConfigurationImportSelector筛选符合条件的配置类,实现按需装配。开发者可专注业务,享受“开箱即用”的便捷体验。(238字)
|
2月前
|
架构师 关系型数据库 MySQL
【Java架构师体系课 | MySQL篇】③ Explain执行计划详解
Explain用于分析SQL执行计划,通过模拟优化器行为揭示查询性能瓶颈。它展示索引使用、扫描行数等信息,帮助优化查询语句,提升数据库效率。
297 6
【Java架构师体系课 | MySQL篇】③ Explain执行计划详解
|
2月前
|
存储 缓存 关系型数据库
为什么MySQL8.0 要取消查询缓存?
MySQL查询缓存曾用于提升SELECT性能,通过缓存结果避免重复执行,但因频繁失效、内存开销大、一致性问题及不均查询分布等缺陷,自8.0版本起被彻底移除,以优化整体性能与维护性。
163 1
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
21402 2
|
8月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
2月前
|
SQL 架构师 关系型数据库
【Java架构师体系课 | MySQL篇】⑤ 索引优化实战一
本文深入解析MySQL索引优化原理,涵盖联合索引使用、覆盖索引、索引下推、filesort排序机制及trace工具分析执行计划选择等内容,并结合实际案例提供索引设计原则与SQL优化策略。
155 5
|
2月前
|
Java 关系型数据库 MySQL
基于springboot的电脑商城系统
本研究聚焦3C数码电商系统的技术升级,针对传统架构性能瓶颈与用户体验不足问题,基于SpringBoot微服务框架构建高并发、易扩展的新型电商平台,结合MySQL、B/S架构与Java技术,提升系统稳定性与智能化水平。
|
2月前
|
人工智能 运维 监控
Flink 智能调优:从人工运维到自动化的实践之路
作者:黄睿 阿里云智能集团产品专家 本文基于阿里云 Flink 平台的实际实践经验整理,希望能为广大流计算从业者提供有价值的参考。
265 26
Flink 智能调优:从人工运维到自动化的实践之路
|
2月前
|
easyexcel Java 数据库连接
如何实现百万级数据从 Excel 导入到数据库?
本文介绍百万级Excel数据导入数据库的优化方案,涵盖内存溢出、性能瓶颈与错误处理三大问题。通过EasyExcel流式读取避免内存溢出,结合多线程并发读取多个sheet,并利用生产者-消费者模式提升处理效率。采用批量插入与事务管理提高数据库写入性能,同时设计数据校验、重试机制与日志记录保障容错性,确保大规模数据导入稳定高效。
279 0
|
6月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1115 0