揭开MySQL索引神秘面纱(3)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 揭开MySQL索引神秘面纱


四、聚簇索引、非聚簇索引区别

聚簇索引、非聚簇索引也被称之为主索引、二级索引。


那么如何区分聚簇索引和非聚簇索引呢!


首先看一下Innodb引擎下,创建表生成的文件,可以看到有俩个ibd文件。


image.png


看到这里不知道大家有没有疑问,为什么看有的文章中也会有frm文件呢!但是在这里怎么没有呢!


原因是在MySQL8.0之后将源数据都存储到了表空间中,所以也就不存在frm文件喽!


都知道这个idb文件会存储数据信息和索引信息。


那再来看一下Myisam存储引擎创建表生产的文件。


image.png


从图中可以看到创建一个表会生成三个文件,扩展名分别为MYD、MYI、sdi。


MYD:是表数据文件(保存数据的文件)


MYI :是表索引文件(保存索引的文件)


那么就可以得出一个结论


只要数据跟索引存储在一个文件里,那就是聚簇索引,否则就是非聚簇索引。


这个时候就会有人问了,表中有主键的时候,idb文件中存储的是主键+数据,那么当没有设置主键时怎么办呢!


记住这一句话,在Innodb中,数据插入时必须跟一个索引值进行绑定,如果没有主键那就选择唯一索引,如果没有唯一索引就会选择一个6Byte的rowid。


五、表中存在多个索引数据是如何存储的

看了上文的解释,有没有产生过一丝疑问,在Innodb存储引擎下,如果存在多个索引,是不是会产生多个idb文件。


在Innodb中数据只会保存一份,如果有多个索引,会维护多个B+Tree


例如:表字段 id,name,age,sex。


id设置为主键索引(聚簇索引),name设置为普通索引,那么数据到底会存储几份呢!


不管一个表中设置多少个索引,数据只会存储一份,但是这张表会维护多个B+Tree。


按照这个案例中id为主键索引,name为普通索引,那么在这张表中就会维护俩颗B+Tree。


id主键索引跟数据存储在一起,name索引所在的B+Tree中叶子节点存储的是主键id的值。


对应的图就是以下俩幅图,可以好好的看一下。


image.png


image.png




最后给大家总结一个点:在Innodb中,一定有聚簇索引,其它索引都是非聚簇索引。


这里简单提一下myisam中只有非聚簇索引。


六、索引的几个技术名词

在面试中往往会问这几个关键词,分别为回表、覆盖索引、最左侧原则、索引下推,一定要知道哈!


1. 回表

网上对回表的解释各种各样,咔咔给你说种简单易懂的,但前提是你需要把聚簇索引、非聚簇索引区分清楚。


还是用上边的案例,id为主键索引,name为普通索引。


此时查询语句为select id,name,age from table where name = 'kaka'


那么这条语句会先在name的这颗B+Tree中寻找到主键id,然后在根据主键id的索引获取到数据并且返回。


其实这个过程就是从非聚簇索引跳转到聚簇索引中查找数据,被称为回表,也就是说当你查询的字段为非聚簇索引,但是非聚簇索引中没有将需要查询的字段全部包含就是回表。


在这个案例中,非聚簇索引name的叶子节点只有id,并没有age,所以会跳转到聚簇索引中,根据id在查询整条记录返回需要的字段数据。


2. 覆盖索引

覆盖索引,根据名字都能理解的差不多,就是查询的所有字段都创建了索引!


此时查询语句为select id,name from table where name = 'kaka'


那么这条语句就是使用了覆盖索引,因为id和name都为索引字段,查询的字段也是这俩个字段,所以被称为索引覆盖。


也就是说当非聚簇索引的叶子节点中包含了需要查询的字段时就被称为覆盖索引


3. 最左匹配

最左匹配原则是在组合索引中存在的。


还是用之前表信息:表字段 id,name,age,sex。


此时给name,age设置成组合索引。


以下语句中那个不符合最左侧原则。


select * from table where name = ? and age = ?


select * from table where name = ?


select * from table where age = ?


select * from table where age= ? and name= ?


可以自行做一下测验哈!是只有第三条语句不会用到索引,其它的三条语句都会符合最左侧原则。


关于这个最左侧原则远远不止这么简单的,一试就是一个坑,关于这部分内容咔咔后期会在优化文章中提到。


4. 索引下推

还是使用这条sql语句。


select * from table where name = ? and age = ?


索引下推是在MySQL5.6及以后的版本出现的。


之前的查询过程是,先根据name在存储引擎中获取数据,然后在根据age在server层进行过滤。


在有了索引下推之后,查询过程是根据name、age在存储引擎获取数据,返回对应的数据,不再到server层进行过滤。


当你使用Explain分析SQL语句时,如果出现了index condition pushdown那就是使用了索引下推,索引下推是在组合索引的情况出现几率最大的。


七、索引存储在什么地方

索引的数据文件是存储在磁盘中的,也是需要进行持久化操作。


但是当使用索引时会把数据从磁盘读取到内存中,读取方式为分块读取。


这时就要涉及到操作系统的概念,操作系统在磁盘中获取数据,假设现在要取的数据大小是1kb,但操作系统并不会只取出你需要的这1kb,而是会取出4kb的数据。


为什么会是4kb,因为在操作系统中一页的数据就是4kb。


那又为什么只需要1kb而取出整页的数据呢!


那就又会涉及到另一个概念那就是局部性原理:数据和程序都有聚集成群的倾向,在访问了一条数据之后,在之后有极大的可能再次访问这条数据和这条数据的相邻数据。


所以说MySQL的Innodb存储引擎,在读取数据时也会采取这种局部性原理,每次读取的数据是16kb。


在Innodb存储引擎下每页的大小默认为16kb,这个参数也可以进行调整,参数为innodb_page_size。


最后一点:


既然标题问的是索引数据存储在什么地方,在第一句就直接回答了索引是存储在磁盘中,并且以页为单位进行从磁盘往内存读取。


那为什么不直接存储在内存中呢!你有没有这个疑问呢!


如果索引数据只存储在内存中,那么当电脑关机,服务器宕机之后,就需要重新生成索引,这种的效率是十分低的。


八、总结

以上就是咔咔对索引的理解,在尽最大的可能将知识点说全面。


如果还有遗漏,或者文章中有错误的地方还请各位能给出提议。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
存储 自然语言处理 关系型数据库
MySQL高级篇——索引的创建与设计原则
索引的分类与使用、MySQL8.0索引新特性、适合创建索引的情况、不适合创建索引的情况
MySQL高级篇——索引的创建与设计原则
|
16天前
|
存储 SQL 关系型数据库
MySQL高级篇——索引失效的11种情况
索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4
MySQL高级篇——索引失效的11种情况
|
16天前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
162 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
16天前
|
存储 缓存 关系型数据库
MySQL高级篇——存储引擎和索引
MyISAM:不支持外键和事务,表锁不适合高并发,只缓存索引,内存要求低,查询快MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务、行级锁、外键,有一个毫无疑问的缺陷就是崩溃后无法安全恢复。5.5之前默认的存储引擎优势是访问的速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用针对数据统计有额外的常数存储。故而 count(*) 的查询效率很高表名.frm 存储表结构;表名.MYD 存储数据 (MYData);
MySQL高级篇——存储引擎和索引
|
16天前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
5天前
|
关系型数据库 MySQL 数据库
MySQL删除全局唯一索引unique
这篇文章介绍了如何在MySQL数据库中删除全局唯一的索引(unique index),包括查看索引、删除索引的方法和确认删除后的状态。
27 9
|
9天前
|
关系型数据库 MySQL 数据库
MYSQL索引的分类与创建语法详解
理解并合理应用这些索引类型,能够有效提高MySQL数据库的性能和查询效率。每种索引类型都有其特定的优势,适当地使用它们可以为数据库操作带来显著的性能提升。
28 3
|
13天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
15天前
|
存储 SQL 关系型数据库
使用MySQL Workbench进行数据库备份
【9月更文挑战第13天】以下是使用MySQL Workbench进行数据库备份的步骤:启动软件后,通过“Database”菜单中的“管理连接”选项配置并选择要备份的数据库。随后,选择“数据导出”,确认导出的数据库及格式(推荐SQL格式),设置存储路径,点击“开始导出”。完成后,可在指定路径找到备份文件,建议定期备份并存储于安全位置。
149 11
|
2月前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
下一篇
无影云桌面