您的位置:首页 > 健康 > 美食 > 智慧园区管理系统_山东临朐门户网站_培训报名_百度竞价调价软件

智慧园区管理系统_山东临朐门户网站_培训报名_百度竞价调价软件

2025/2/24 8:26:41 来源:https://blog.csdn.net/2402_84916296/article/details/145807599  浏览:    关键词:智慧园区管理系统_山东临朐门户网站_培训报名_百度竞价调价软件
智慧园区管理系统_山东临朐门户网站_培训报名_百度竞价调价软件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


索引


MySQL中的页


为什么要使用页?


.ibd文件中最重要的结构体就是Page(页),页是内存与磁盘交互的最小单元,默认大小为16KB,每次内存与磁盘的交互至少读取一页,,所以在磁盘中每个页内部的地址都是连续的;

之所以至少读取一页记录,而不是一行记录,是因为在使用数据的过程中,根据局部性原理,将来要使用的数据,大概率与当前访问的数据在空间上是临近的

所以一次从磁盘中读取一页的数据放入内存中,当下次查询的数据还在这个页中时,就可以从内存中直接读取,从而减少磁盘I/O提高性能;

在这里插入图片描述


查看页的大小的语法


show variables like 'innodb_page_size';  -- 可以通过系统变量innodb_page_size,查看页的大小

在这里插入图片描述

16384 / 1024 = 16 ( 16KB为页空间的默认大小 )

在这里插入图片描述


数据页


概念

在MySQL中有多种不同类型的页,最常用的就是用来存储数据和索引的"索引页",也叫做"数据页",但不论哪种类型的页,都会包含页头(File Header)页尾(File Trailer),页的主体信息使用数据"行"进行填充;


结构

数据页的基本结构如下图所示:

在这里插入图片描述


页文件头和页文件尾

在这里插入图片描述


页主体


页主体部分是保存真实数据的主要区域,每当创建一个新页,都会自动分配两个行,一个是页内最小行 Infimun,另一个是页内最大行Supremun,这两个行并不存储任何真实信息,而是做为数据行链表的头和尾,第一个数据行有一个记录下一行的地址偏移量的区域next_record,将页内所有数据行组成了一个单向链表,此时新页的结构如下所示:

在这里插入图片描述


当向一个新页插入数据时,将Infimun 连接第一个数据行,最后一行真实数据行连接Supremun,这样数据行就构建成了一个单向链表,更多的行数据插入后,会按照主键从小到大的顺序进行链接,如下图所示

在这里插入图片描述


页目录


一个数据页大小为16KB,但是一条记录可能只有4Byte,很可能一个数据页就可以存储几百条记录,这几百条记录是以一个单向链表的结构组织在一起,查询其中一条记录的时间复杂度为 O(N),为了优化查询效率,我们引入页目录:

在这里插入图片描述


数据页头


数据页头记录了当前页保存数据相关的信息,如下图所示:

在这里插入图片描述


B+在MySQL索引中的应用


非叶子节点保存索引数据,叶子节点保存真实数据,如下图所示:

在这里插入图片描述

先加载页到内存,然后找子节点的地址,通过地址找到页,再通过页中的槽找到记录;


计算三层树高的B+树,理论上可以存放多少条记录


在这里插入图片描述


索引分类


主键索引


  • 当在一个表上定义一个主键PRIMARY KEY 时,自动创建索引,索引的值就是主键的值;

  • InnoDB使用它作为聚簇索引

  • 推荐为每个表定义一个主键。如果没有逻辑上唯一且非空的列或列集可以使用主键,则添加一个自增列


普通索引


  • 为了提升查询效率,工作中通常为查询频繁的列创建索引,自创建的索引就是普通索引;

  • 普通索引是最基本的索引类型,没有唯一性的限制,可能为一个列创建索引,也可能为多列创建组合索引

  • 为多个列创建组合索引,该组合索引称为复合索引组全索引

  • 对于一个有大量重复值的列(如性别列,状态列…),不建议创建索引。

  • 创建索引之后都会生成一棵索引树,创建多少个索引就生成多少棵索引树;

  • 创建索引后,生成的索引树也是会占用空间的,所以创建索引时也需要慎重考虑一下需不需要,索引树越多,对insert , drop , update操作的影响会比较大,因为进行这些操作需要更新维护索引树。


唯一索引


  • 当在一个表上定义一个唯一键 UNQUE 时,自动创建唯一索引
  • 与普通索引类似,但区别在于唯一索引的列不允许有重复值

全文索引


  • 基于文本列 (CHAR、VARCHAR 或 TEXT列) 上创建,以加快对这些列中包含的数据查询和 DML 操作
  • 用于全文搜索,仅 MylSAM 和 InnoDB 引擎 支持。

聚集索引


  • 与主键索引是同义词

  • 如果没有为表定义PRIMARY KEY,InnoDB 使用第一个 UNIQUE和 NOT NULL 的列作为聚集索引

在这里插入图片描述

  • 如果表中没有 PRIMARY KEY 或合适的 UNIQUE 索引,InnoDB会为新插入的行生成一个行号,并用 6字节的 ROW_ID 字段记录(这是数据行中的隐藏列之一) ,ROW_ID 单调递增,并使用 ROW_ID 做为索引。

  • 所以主键值的列一定会填入值,可能是 primary key 所在列的值,也可能是 第一个 UNIQUE和 NOT NULL 列所在的值,也可能是自动生成的 ROW_ID 所在的列的值。


非聚集索引 / 二级索引


聚集索引以外的索引称为非聚集索引二级索引;

二级索引中的每条记录都包含该行的主键列,以及二级索引指定的列;

InnoDB使用这个主键值,来搜索聚集索引中的行,这个过程称为回表查询。


非聚集索引通俗讲解


首先,想象一下你有一本书,这本书里面有很多章节和内容。当你翻到某个章节时,你需要先翻到书的目录(索引)找章节的页码,然后根据页码找到对应的内容。

非聚集索引就像这个目录,它告诉你某个数据的位置,但它本身并不包含所有的数据,只是指向数据的位置。也就是说,非聚集索引是单独存放的,它和数据表本身是分开的。


非聚集索引的查询过程


假设你有一个员工表 employees,字段包括 emp_id(员工ID)、emp_name(员工姓名)和 salary(薪水)。现在,你要查询某个员工的名字和薪水,查询条件是 emp_id = 101

查询步骤

  1. 查索引:数据库首先查看非聚集索引,假设你查询的是 emp_id,索引中会存有 emp_id 和它对应的记录位置(类似目录中的页码)。

  2. 找到位置:通过查找索引,数据库知道 emp_id = 101 的记录在哪个位置(就像从目录找到具体页码)。

  3. 回到数据表:数据库根据索引找到的数据位置,去原始的数据表中找出完整的记录(因为非聚集索引本身不存储实际数据,只是位置指针)。

  4. 返回结果:拿到数据后,返回查询的结果。

例子

假设你的索引包含了员工ID(emp_id)和它在表中的位置。你要查找 emp_id = 101 对应的 emp_namesalary,非聚集索引会告诉你 emp_id = 101 在表中的位置,然后数据库去表里找到完整的员工信息。

总结

  • 非聚集索引就像一本书的目录,它只包含“数据的位置”,而不包含实际的数据。
  • 查询时,数据库首先查索引(目录),然后再去数据表中获取完整的数据(就像根据目录找到书的具体内容)。

这种方式比直接在表里查要快,但因为需要两次查找(先查索引,再查数据表),它的查询效率比聚集索引稍慢一些。


回表查询


想象你有两个文件夹:

  1. 一个文件夹里存的是“用户信息”(比如:名字、年龄等)。
  2. 另一个文件夹里存的是“订单信息”(比如:订单号、金额等)。

假设你想做一件事情:查找每个订单对应的用户名字。

  • 你已经知道订单的 user_id(每个订单都有一个用户 ID),但是文件夹 2(订单信息)里没有用户的名字,只有 user_id

  • 于是,你就需要去文件夹 1(用户信息)找出这个 user_id 对应的名字。

  • 这个过程,就是所谓的“回表”查询。数据库帮你去一个表里找你要的额外信息,把它“带回来”给你。

简单来说,回表就是数据库去别的表找额外的数据,把你想要的完整信息拿回来。


索引覆盖


当一个select语句使用了普通索引,且查询列表中的列,刚好是创建普通索引时的所有或部分列,这时就可以直接返回数据,而不用回表查询,这样的现象称为索引覆盖。


简单来说,在数据库中,索引覆盖意味着查询可以直接通过索引获取所需的所有数据,而无需访问表的完整记录。换句话说,索引包含了查询所需的全部信息。

假设我们有一个表 employees,它记录了员工的信息,包含以下字段:

  • emp_id(员工ID)
  • emp_name(员工姓名)
  • salary(薪资)
  • department(部门)

我们在表上建立了一个索引,这个索引只包含 emp_idemp_name 字段。

现在,我们查询某个员工的姓名:

SELECT emp_name FROM employees WHERE emp_id = 101;

如果我们查询的字段(在这个例子中是 emp_name)在索引中就能找到,并且这个索引包含了查询所需的全部数据,那么数据库就不需要回到表里去查找,它可以直接从索引中拿到结果。

这种情况就是索引覆盖,它避免了访问数据表,因此提高了查询速度。


总结


在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com