数据库学习笔记一:索引篇

发布时间:2023-09-24 16:00

目录

一、索引篇

InnoDB 是如何存储数据的?

B+ 树是如何进行查询的?

数据页很多时怎么办?建立页索引

B+ 树的特点:

聚簇索引和二级索引

总结

为什么 MySQL 采用 B+ 树作为索引?

怎样的索引的数据结构是好的?

什么是二分查找树?

什么是自平衡二叉树(AVL树)?

什么是 B 树?

什么是 B+ 树?

1、单点查询

2、插入和删除效率

3、范围查询

MySQL 中的 B+ 树

总结

索引失效有哪些?

索引存储结构长什么样?

对索引使用左或者左右模糊匹配

对索引使用函数

对索引进行表达式计算

对索引隐式类型转换

联合索引非最左匹配

WHERE 子句中的 OR

总结

MySQL 使用 like “%x“,索引一定会失效吗?

题目一

题目二

count(*) 和 count(1) 有什么区别?哪个性能最好?

哪种 count 性能最好?

为什么要通过遍历的方式来计数?

如何优化 count(*)?


学习资料来源:小林coding

仅用于个人学习,侵权删除

一、索引篇

InnoDB 是如何存储数据的?

记录是按照行来存储的,但是数据库的读取并不以「行」为单位,否则一次读取(一次 I/O 操作)只能处理一行数据,效率会非常低。

因此,InnoDB 的数据是按「数据页」为单位来读写的,也就是说,当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位整体读入内存

数据库的 I/O 操作的最小单位是页,InnoDB 数据页的默认大小是 16KB,意味着数据库每次读写都是以 16KB 为单位的,一次最少从磁盘中读取 16K 的内容到内存中,一次最少把内存中的 16K 内容刷新到磁盘中。

数据页包括七个部分,结构如下图:

数据库学习笔记一:索引篇_第1张图片

 在 File Header 中有两个指针,分别指向上一个数据页和下一个数据页,连接起来的页相当于一个双向的链表,如下图所示:数据库学习笔记一:索引篇_第2张图片

数据页中的记录按照「主键」顺序组成单向链表,单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索。

因此,每个数据页中有一个页目录,起到记录的索引作用,就像书本一样,针对书中内容的每个章节设立了一个目录,想看某个章节的时候,可以查看目录,快速找到对应的章节的页数,而数据页中的页目录就是为了能快速找到记录。

那 InnoDB 是如何给记录创建页目录的呢?页目录与记录的关系如下图:数据库学习笔记一:索引篇_第3张图片

页目录创建的过程如下:

  1. 将所有的记录分组,这些记录包括最小记录和最大记录,但不包括标记为“已删除”的记录
  2. 每个记录组的最后一条记录就是组内最大的那条记录,并且最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned 字段(上图中粉红色字段)
  3. 页目录用来存储每组最后一条记录的地址偏移量,这些地址偏移量会按照先后顺序存储起来,每组的地址偏移量也被称之为槽(slot)每个槽相当于指针指向了不同组的最后一个记录

从图可以看到,页目录就是由多个槽组成的,槽相当于分组记录的索引。然后,因为记录是按照「主键值」从小到大排序的,所以我们通过槽查找记录时,可以使用二分法快速定位要查询的记录在哪个槽(哪个记录分组),定位到槽后,再遍历槽内的所有记录,找到对应的记录,无需从最小记录开始遍历整个页中的记录链表。

疑问

  • 「槽对应的值都是这个组的主键最大的记录,如何找到组里最小的记录」
  • 解决办法是:首选确定记录所在槽,比如确定在槽3,我们通过槽 3 找到 槽 2 对应的记录,再往下。
  • 槽内记录会不会很多,因为记录是单向链表串联,遍历时速度会变慢?
  • InnoDB 对每个分组中的记录条数都是有规定的,槽内的记录就只有几条:第一个分组中的记录只能有 1 条记录;最后一个分组中的记录条数范围只能在 1-8 条之间;剩下的分组中记录条数范围只能在 4-8 条之间

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号