mysql核心知识-----索引

索引的概念和用途

索引的概念 : 在mysql内部,IO数据的单位是page页(16KB),以B+树的形式将所有的page页进行组织,形成的数据结构和与其配套的
查找算法叫做索引。 (听到即懵逼????, 慢慢向下看, 疑惑最终回解决)
索引的用途: 用于提高数据库查询效率。 但是呢,查询速度的提高,但是对于增删查改的效率会降低。
所以:索引的核心在于:提高海量数据的查询速度。

索引的类型:
1, 主键索引
2, 唯一索引
3, 普通索引(辅助索引)
4, 全文索引。(不用关心)

对于索引的SQL操作比较简单,就不细说了。

而且,存储引擎的不同,索引会有些区别。
无特殊说明,往下全是 innodb存储引擎的情况

应用层的mysql(各种操作语句)与底层的mysql数据库(磁盘上的文件)交互

我们知道,数据库的主要功能是管理数据,而数据库存储数据肯定是以文件的形式保存在磁盘当中,这样才能永久保存。
而应用层的mysql不可能直接去访问磁盘中的数据, 肯定是将磁盘中的数据加载到内存,然后mysql与数据进行操作处理。
当然了,肯定也不是将磁盘中所有的数据库中的所有数据加载到内存。

其实,每当我们启动mysql的时候,我们都会在内存中申请一段空间 buffer pool =128M ,用于加载磁盘中的数据。
当mysql操作完数据后,buffer pool 以某种刷新策略刷新回磁盘中,做到永久保存。

那么, 问题又来了。 每次从磁盘中读取多少的数据呢?

IO的单位

系统读取磁盘中的数据,是以块为单位,是4KB。 (这里有疑惑可以百度一下,涉及硬盘相关的硬件知识)
然而数据库是专门用来管理数据的,为了提高IO效率 ------->以page单位 (16KB)。
也就是说:当mysql操作数据的时候,将需要操作的数据加载到内存中的buffer pool中, 是以page单位的。
刷新到磁盘中,也是以page为单位的。

然后的话,mysql操作数据的时候,肯定是磁盘中有数据,内存中也有数据。
(因为只用将需要操作的相关数据以page为单位加载到内存,这里说的不是拼凑要操作的数据,
而是建立索引后,数据会排序,将数据上下相连满16KB一个page,加载到内存)

为什么IO单位是page(16KB)呢? 需要多少数据加载多少数据到内存不好吗?
原因 : 提高IO效率, 这次要操作的数据 和下次要操作的数据可能都在一个page。
在这里插入图片描述

深入理解索引

在这里插入图片描述

我们这样插入几组数据,然后再查询会发现:按照主键进行排序。 问题又来了, 为什么会排序呢?
在这里插入图片描述

如何理解单个page(16KB)
在这里插入图片描述
128M * 1024 / 16= 8192 也就是说,128M的buffer poll 能容纳 8192个page,根据主键查找一条记录需要遍历每个page,
就算是页内查找效率提高,那查找出来也是够呛。 如何提高呢? ------> 给page页加上目录。
在这里插入图片描述
目录项 : 最小数据的键值 + page地址
目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。
一个目录页16KB ,而一个键值4byte 一个地址是4byte ---->一个目录页可以存放 16 * 1024 / 8 = 2048个目录项,而一个buffer pool最多才有8000多个page
也就是说:树的高度非常低 -------> 只用将少量高频访问的目录页加载到内存,就完全可以极大的提高IO效率。

为了防止线性遍历目录页,顶层的目录页仍旧可以继续加目录页,如:
在这里插入图片描述

而这样的数据结构就是 : B+ 树。

对比其他数据结构:
链表?线性遍历
二叉搜索树?在完全有序的情况下,退化成为单边树
AVL &&红黑树?虽然是平衡或者近似平衡,但是毕竟是二叉结构,相比较多阶B+,意味着树整体过高,大家都
是自顶向下找,层高越低,意味着系统与硬盘更少的IO Page交互
Hash?官方的索引实现方式中, MySQL 是支持HASH的,不过 InnoDB 和 MyISAM 并不支持.Hash跟进其算法特
征,决定了虽然有时候也很快(O(1)),不过,在面对范围查找就明显不行

与B树的区别:
B树的所有节点存放数据+page指针,而B+树只有叶子节点存放数据,非叶子节点(目录页)存放最小数据的键值和page指针
B树叶子节点不连续, B+树叶子节点连续 (更有利于范围查找)。

查找效率是提高了, 你再想想增删查改 ------> 基本上就是整个结构都要修改 。

聚簇索引 VS 非聚簇索引

都是B+树的结构。
用户数据 : 可以理解为一条条插入的记录
索引数据 : 一个page页内中的目录字段 + page指针等等,,
在这里插入图片描述

普通(辅助)索引

MySQL 除了默认会建立主键索引外,我们用户也有可能建立按照其他列信息建立的索引,一般这种索引可以
叫做辅助(普通)索引。

MyISAM的辅助索引和主键索引无区别, 就是上面的非聚簇索引。 (用户数据和索引数据分离)
InnoDB 的辅助索引中叶子节点并没有数据,而只有对应记录的主键值。
所以通过辅助(普通)索引,找到目标记录,需要两遍索引**:首先检索辅助索引获得主键,然后用主键到主索引中检
索获得记录。这种过程,就叫做回表查询**
为何 InnoDB 针对这种辅助(普通)索引的场景,不给叶子节点也附上数据呢?原因就是太浪费空间了。

还有一种索引 ------ 唯一索引, 不能重复,可以为null, 加上 not null 等价于 主键索引。

这里的什么主键索引 + 唯一索引 + 辅助索引的 特性知识就不罗嗦了, 随便百度或者翻学校的烂教材都能找到。

什么字段适合做主键?

比较频繁作为查询条件的字段应该创建索引
唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
更新非常频繁的字段不适合作创建索引
不会出现在where子句中的字段不该创建索引

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通过全部用例

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值