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

目录
相关文章
|
机器学习/深度学习 NoSQL Redis
Redis高可用之集群架构(第三部分)
Redis高可用之集群架构(第三部分)
|
5月前
|
架构师 关系型数据库 MySQL
【Java架构师体系课 | MySQL篇】③ Explain执行计划详解
Explain用于分析SQL执行计划,通过模拟优化器行为揭示查询性能瓶颈。它展示索引使用、扫描行数等信息,帮助优化查询语句,提升数据库效率。
542 6
【Java架构师体系课 | MySQL篇】③ Explain执行计划详解
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
24026 2
|
16天前
|
SQL 算法 关系型数据库
击穿 InnoDB 事务隔离级别:RC 与 RR 的底层实现、锁机制、MVCC 与幻读终极拆解
本文深入剖析InnoDB事务隔离原理,聚焦RC(读已提交)与RR(可重复读)的核心差异:从锁机制(记录锁/间隙锁/临键锁)、MVCC可见性规则(Read View生成时机)到幻读解决方案。结合可复现实例与Java实战,助你彻底理解底层逻辑,规避90%的数据不一致与死锁问题。
159 2
|
3月前
|
负载均衡 Java Spring
Feign 和 OpenFeign 有什么区别?
Feign是Netflix开发的声明式HTTP客户端,简化Web服务调用。OpenFeign是Spring Cloud对其的扩展,集成负载均衡、服务发现等组件,提供自动配置,更适用于Spring生态。
352 1
|
5月前
|
存储 缓存 关系型数据库
为什么MySQL8.0 要取消查询缓存?
MySQL查询缓存曾用于提升SELECT性能,通过缓存结果避免重复执行,但因频繁失效、内存开销大、一致性问题及不均查询分布等缺陷,自8.0版本起被彻底移除,以优化整体性能与维护性。
253 1
|
5月前
|
SQL 架构师 关系型数据库
【Java架构师体系课 | MySQL篇】⑤ 索引优化实战一
本文深入解析MySQL索引优化原理,涵盖联合索引使用、覆盖索引、索引下推、filesort排序机制及trace工具分析执行计划选择等内容,并结合实际案例提供索引设计原则与SQL优化策略。
287 5
|
5月前
|
Java 关系型数据库 MySQL
基于springboot的电脑商城系统
本研究聚焦3C数码电商系统的技术升级,针对传统架构性能瓶颈与用户体验不足问题,基于SpringBoot微服务框架构建高并发、易扩展的新型电商平台,结合MySQL、B/S架构与Java技术,提升系统稳定性与智能化水平。
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
10月前
|
缓存 NoSQL 算法
高并发秒杀系统实战(Redis+Lua分布式锁防超卖与库存扣减优化)
秒杀系统面临瞬时高并发、资源竞争和数据一致性挑战。传统方案如数据库锁或应用层锁存在性能瓶颈或分布式问题,而基于Redis的分布式锁与Lua脚本原子操作成为高效解决方案。通过Redis的`SETNX`实现分布式锁,结合Lua脚本完成库存扣减,确保操作原子性并大幅提升性能(QPS从120提升至8,200)。此外,分段库存策略、多级限流及服务降级机制进一步优化系统稳定性。最佳实践包括分层防控、黄金扣减法则与容灾设计,强调根据业务特性灵活组合技术手段以应对高并发场景。
2885 7

热门文章

最新文章