MySQL回表查询与索引覆盖的区别是什么
来源:亿速云
时间:2023-05-14 09:46:39 167浏览 收藏
数据库不知道大家是否熟悉?今天我将给大家介绍《MySQL回表查询与索引覆盖的区别是什么》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!
回表查询
InnoDB索引分为两大类,一类是聚集索引(Clustered Index),一类是非聚集索引(Secondary Index)
聚集索引(聚簇索引):叶子节点中存的是整行数据,找到索引也就找到了数据,索引即数据,表中行的物理顺序与键值的逻辑(索引)顺序相同,一个表只能包含一个聚集索引。因为索引(目录)只能按照一种方法进行排序。
非聚集索引(普通索引、非聚簇索引、二级索引):非聚集索引的btree叶子节点中存储的是当行数据的PK(主键)。例如MYISAM通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因。
为什么非主键索引结构叶子结点存储的是主键值?
减少了出现行移动或者数据页分裂时二级索引的维护工作(当数据需要更新的时候,二级索引不需要修改,只需要修改聚簇索引,一个表只能有一个聚簇索引,其他的都是二级索引,这样只需要修改聚簇索引就可以了,不需要重新构建二级索引)
如果需要获取具体的数据,使用非聚集索引时需通过主键返回到聚集索引进行数据查询。着就叫回表查询。扫描了2次索引树。所以效率相对较低。
索引覆盖
索引覆盖就是解决回表查询的一种方案。见名知意,就是查询的所有列均被所使用的索引列覆盖(可以是单列索引也可以是联合索引,通常是联合索引,单列索引很难覆盖查询的所有列)。
因为索引中已经包含了要查询的字段的值,因此查询的时候直接返回索引中的字段值就可以了,不需要再到表中查询,避免了对主键索引的二次查询,也就提高了查询的效率。
id为聚集索引,name为非聚集索引:
select name, age from t where name = 'lcc';
就需要回表查询
索引覆盖:
在SQL中只查询name字段。这样name的索引就覆盖到了所有的查询列。
select name from t where name = 'lcc';
将name的索引修改为联合索引(name, age ),之后还是执行select name, age from t where name = 'lcc'。这样也覆盖到了所有的查询列。
因为覆盖索引必须要存储索引的列值,而哈希索引、空间索引和全文索引等都不存储索引列值,从而只有使用B-Tree索引的数据可以做覆盖索引。
进行索引覆盖查询时,在explain(执行计划)的Extra列可以看到【Using Index】的信息。
索引覆盖的优点
索引条目通常远小于数据行的大小,因为覆盖索引只需要读取索引,极大地减少了数据的访问量。
索引是按照列值顺序存储的,对于IO密集的范围查找会比随机从磁盘读取每一行数据的IO小很多。
一些存储引擎比如MyISAM在内存中只缓存索引,数据则依赖操作系统来缓存,因此要访问数据的话需要一次系统调用,使用覆盖索引则避免了这一点。
InnoDB引擎下的数据库表对覆盖索引尤其有益,这是由于其使用聚簇索引的特性所导致的。因为InnoDB的二级索引在叶子节点中保存了行的主键值,如果二级索引能够覆盖查询,就避免了对主键索引的二次查询。
哪些场景适合使用索引覆盖来优化SQL
当不需要查询整行记录时;
全表count查询优化;
Limit分页查询;
哪些情况下不要建索引
表记录太少
经常增删改的表或者字段(如用户余额)
Where条件里用不到的字段不创建索引
过滤性不好的不适合建索引(如性别)
索引下推
索引下推优化是 MySQL 5.6 引入的, 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数
建立联合索引:
KEY `username` (`name`,`age`) )
执行:
select * from user2 where name like 'j%' and age=99;
上面的查询sql符合索引的最左前缀原则,所以将会用到 username 索引
5.5中上面这个 SQL 的执行流程是这样的:
首先 MySQL 的 server 层调用存储引擎获取第一个以 j 开头的 username。
存储引擎找到 username=‘j’ 的第一条记录后,在 B+Tree 的叶子结点中保存着主键 id,此时通过回表操作,去主键索引中找到该条记录的完整数据,并返回给 server 层。
server 层拿到数据之后,判断该条记录的 age 是否为 99,如果 age=99,就把该条记录返回给客户端,如果 age!=99,那就就丢弃该记录。
5.6中上面这个 SQL 的执行流程是这样的:
MySQL 的 server 层首先调用存储引擎定位到第一个以 j 开头的 username。
找到记录后,存储引擎并不急着回表,而是继续判断这条记录的 age 是否等于 99,如果 age=99,再去回表,如果 age 不等于 99,就不去回表了,直接继续读取下一条记录。
理论要掌握,实操不能落!以上关于《MySQL回表查询与索引覆盖的区别是什么》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
292 收藏
-
119 收藏
-
324 收藏
-
308 收藏
-
381 收藏
-
101 收藏
-
499 收藏
-
361 收藏
-
113 收藏
-
434 收藏
-
335 收藏
-
242 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习