一文读懂Mysql数据库索引原理

MyISAM 存储引擎索引实现: MyISAM 索引文件(磁盘上表对应.MYI)和数据文件(MYD)是分离的(非聚集)
InnoDB 存储引擎索引实现: InnoDB 索引实现(聚集)

  1. 表数据文件本身就是B+Treee 组织的一个索引结构文件
  2. 聚集索引-叶子节点包含了完整的数据记录
  3. 为什么建议INnoDB表必须建主键,并且推荐推荐使用整形的自增主键? 如果没有建立主键,数据会帮找一列(唯一索引)如果没有则默认给加一个类似自增的主键。【,存储空间,比较性能整形效率高,自增的会一直往后面加,不会分裂或者说调整数】
  4. 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
问:为什么InnoDB表必须有主键。并且推荐使用整型的自增主键:

1、如果设置了主键,那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增)。

2、如果表使用自增主键
那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,主键的顺序按照数据记录的插入顺序排列,自动有序。当一页写满,就会自动开辟一个新的页

3、如果使用非自增主键(如果身份证号或学号等)
由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

问:为什么非主键索引结构叶子结点存储的是主键值:

减少了出现行移动或者数据页分裂时二级索引的维护工作(当数据需要更新的时候,二级索引不需要修改,只需要修改聚簇索引,一个表只能有一个聚簇索引,其他的都是二级索引,这样只需要修改聚簇索引就可以了,不需要重新构建二级索引)

聚簇索引也称为主键索引,其索引树的叶子节点中存的是整行数据,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。因为索引(目录)只能按照一种方法进行排序。

非聚簇索引(普通索引)的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

存储引擎是针对表的,而不是对数据库的。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

B-Tree : 1.没有双向指针,不能支持范围查找; 2. 非叶子节点存储data,相同高度的数据, 一个分页节点大小16k; 所以横向存储数据就变少
B+Tree: 1.双向指针,支持范围查找;2. 非叶子节点没有存储data,相同高度的数据, 一个分页节点大小16k; 所以横向存储数据就变多

在这里插入图片描述

联合索引必须遵循最左匹配原则:
key: idx_name_age_position(name,age,position) using btree

1: select * from person where name=‘Bill’ and age=‘30’ 【使用索引】
2: select * from person where age=‘30’ and position=‘dev’ 【不使用索引,】
3: select * from person where position=‘dev’ 【不使用索引】

原理:
索引有序排列;
1条sql 因为底层存储先是 一级name 第二age 第三 position ; 因为索引是有序存储的;
2条sql 因为age并非一定顺序存储的,必须建立在一级name相同的前提下才会是age排序。否则age是无序的。
3条sql 因为position 并非一定顺序存储,必须建立在一级name和二级age相同的前提下,position才会是有序的。


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

一页数据总大小16KB
在插入数据的时候,用户数据区就按照主键排序进行插入。虽然会影响插入的效率。但是是为了后续的查询效率;由于用户数据区使用的链表方式存储,链表的优点是插入快查询慢。因为如果查询需要从头到尾顺序进行查找; 所以为了提高查询效率又设计了页目录的方式。 使用数组存储方式,查询快:页面中存储最小索引数据+最小索引数据指针地址(为了方便快速定位数据) ;例如:select * from t1 where a = 30 的时候,首先使用二分查找发进行查询页目录,找到对应的页目录通过指针进行查找用户数据区域数据进行查找;

主键索引
在这里插入图片描述

如果查找7,先是从根节点从上往下找,然后再从最左叶子节点开始进行查找的方式是全表扫描,1->3->5->7;
如果是从根节点从上往下找, 根节点[1,5]->[5,7]->[7455g] 的方式,则是走索引

组合索引: 必须遵守最左匹配原则
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

explain select * from t1 where b>1 – 可以走索引但是,通过索引走完之后,又需要把组合索引下面大于1 所有主键通过回表方式去找对应的数据。这样效率就比走全部扫描更加慢了;所以优先走全部扫描了;
explain select b,c,d from t1 where b>1; 走了索引,因为指定了指定正好是索引字段
explain select a,b,c,d from t1 where b>1; 走了索引,因为指定了指定正好是索引字段
explain select * from t1 where b>6 又走了索引,

explain select b from t1 走索引扫描,因为索引字段存储是不整的数据,叶子节点存的记录行数比主键索引的叶子节点记录全部数据行数要多。它的页就更加少。查询更加快些

explain select a,b,c,d from t1 order by b,c,d; 走索引,因为组合索引已经有所有数据;
explain select * from t1 order by b,c,d; 第一种方案:不走索引,因为不单独排序是走索引,但是还有其他数据在不在组合索引树上,还需要回表;
第二种方案:全表扫描+排序

explain select * from t1 where e=1; 不走索引
explain select * from t1 where e=‘1’; 走索引;
explain select * from t1 where a=1; 走索引
explain select * from t1 where a=‘1’; 不走索引

mysql 如果数据类型转换,非数字字符全部为0
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/590130.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Bert基础(二十)--Bert实战:机器阅读理解任务

一、机器阅读理解任务 1.1 概念理解 机器阅读理解(Machine Reading Comprehension, MRC)就是给定一篇文章,以及基于文章的一个问题,让机器在阅读文章后对问题进行作答。 在机器阅读理解领域,模型的核心能力体现在对…

【Cpp】类和对象#拷贝构造 赋值重载

标题:【Cpp】类和对象#拷贝构造 赋值重载 水墨不写bug 目录 (一)拷贝构造 (二)赋值重载 (三)浅拷贝与深拷贝 正文开始: (一)拷贝构造 拷贝构造函数&…

49. 【Android教程】HTTP 使用详解

在你浏览互联网的时候,绝大多数的数据都是通过 HTTP 协议获取到的,也就是说如果你想要实现一个能上网的 App,那么就一定会和 HTTP 打上交道。当然 Android 发展到现在这么多年,已经有很多非常好用,功能非常完善的网络框…

线性神经网络示例

通过5个条件判定一件事情是否会发生,5个条件对这件事情是否发生的影响力不同,计算每个条件对这件事情发生的影响力多大,写一个线性神经网络模型pytorch程序,最后打印5个条件分别的影响力。 一 在这个场景中,一个线性神经网络&…

ubuntu与redhat的不同之处

华子目录 什么是ubuntu概述 ubuntu版本简介桌面版服务器版 安装部署部署后的设置设置root密码关闭防火墙启用允许root进行ssh登录更改apt源安装所需软件 网络配置Netplan概述配置详解配置文件DHCP静态IP设置设置 软件安装方法apt安装软件作用常用命令配置apt源 deb软件包安装概…

浅拷贝与深拷贝面试问题及回答

1. 浅拷贝和深拷贝的区别是什么? 答: 浅拷贝(Shallow Copy)仅复制对象的引用而不复制引用的对象本身,因此原始对象和拷贝对象会引用同一个对象。而深拷贝(Deep Copy)则是对对象内部的所有元素进…

Git客户端(TortoiseGit)使用详解

1.概述 使用TortoiseGit比直接使用git 客户端和命令实现代码版本管理更为方便,本文根据实际使用情况作一些记录,特别是对于解决冲突的处理。 2.Git安装与配置 下载 Git - Downloads, 可参考Git安装步骤完成Git的安装与配置。 3.TortoiseG…

Linux学习之IP协议

前言: 在学习IP协议i前,我们其实知道网络协议栈是一层层的,上层封装好之后就传给下层,对于我们治安学习到的TCP协议,在对数据进行封装之后,并不是直接就将数据进行传输,而是交给下一层网络层进…

【CTF-Crypto】修复RSA证书入门汇总

证书修复 文章目录 证书修复基础知识Truncated 1Truncated 2Jumbled 基础知识 为什么要引入证书? 在正常题目中,大部分直接给出了数字,但是数字在现实世界中传输不稳定,容易在某处出现错误,所以我们将所有的数字信息…

[嵌入式系统-61]:RT-Thread-内核:原子操作的支持, 原子操作与互斥锁的比较

目录 原子操作 1. 原子操作简介 2. 原子操作的优点 3. RT-Thread 原子操作的实现与使用方法 4. RT-Thread 原子操作 API 原子读 原子写 原子数据交换 原子加 原子减 原子异或 原子与 原子或 原子标志检查与置位 原子标志清除 原子比较与交换 5. 综合示例 原子…

有公网IP的好处?

1. 维护远程连接需求的解决方案 公网IP是指可以通过互联网直接访问的IP地址,相对于私有IP地址而言具有重要的好处。公网IP的最大好处之一是解决了各行业客户的远程连接需求。由于天联组网操作简单、跨平台应用、无网络要求以及独创的安全加速方案等原因&#xff0c…

牛客美团2024年春招第一场笔试【技术】解题

1.小美的平衡矩阵 小美拿到了一个n∗n的矩阵,其中每个元素是 0 或者 1。 小美认为一个矩形区域是完美的,当且仅当该区域内 0 的数量恰好等于 1 的数量。 现在,小美希望你回答有多少个i∗i的完美矩形区域。你需要回答1≤i≤n的所有答案 输出…

实现优先队列——C++

目录 1.优先队列的类模板 2.仿函数的讲解 3.成员变量 4.构造函数 5。判空,返回size,返回队头 6.插入 7.删除 1.优先队列的类模板 我们先通过模板来进行初步了解 由上图可知,我们的模板里有三个参数,第一个参数自然就是你要存储的数…

ServiceNow 研究:通过RAG减少结构化输出中的幻觉

论文地址:https://arxiv.org/pdf/2404.08189 原文地址:rag-hallucination-structure-research-by-servicenow 在灾难性遗忘和模型漂移中,幻觉仍然是一个挑战。 2024 年 4 月 18 日 灾难性遗忘: 这是在序列学习或连续学习环境中出现…

工业光源-环形光源-特点

◆高密度LED排列,科学的结构设计; ◆从360方向照射,消除阴影; ◆中间开孔,使光源与相机镜头完美契合: ◆多角度可选,可适应不同工作距离的应用; ◆可选配漫射板,使光线均…

C++算法之sort

sort默认排序方式为从小到大 vector<int> v{3,2,6,1,-2};sort(v.begin(),v.end());for(int i0;i<v.size();i){cout<<v[i]<<" ";}想要sort从大到小排序&#xff1a; 1.是自定义cmp 2.使用自带的函数&#xff1a;

Redis__事务

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a;Redis__事务 ⏱️ 创作时间&#xff1a;2024年05月02日 ———————————————— 这里写目录标题 文章目…

【Web】CTFSHOW 中期测评刷题记录(1)

目录 web486 web487 web488 web489 web490 web491 web492 web493 web494 web495 web496 web497 web498 web499 web500 web501 web502 web503 web505 web506 web507 web508 web509 web510 web486 扫目录 初始界面尝试文件包含index.php&am…

WSL2连接Windows主机的Mysql

文章目录 需求查看主机IP防火墙设置Mysql设置允许远程连接WSL2连接Mysql 需求 在WSL2&#xff08;本机Ubuntu20.04&#xff09;运行的程序需要将数据写入到本机的Mysql服务器中 查看主机IP 两种办法&#xff1a; Windows主机输入 ipconfig&#xff0c;找到带有WSL后缀的部分…

C 语言笔记:字符串处理函数

一、获取字符串长度函数 头文件&#xff1a;#include <string.h> 函数定义&#xff1a;size_t strlen(const char *s); 函数功能&#xff1a; 测字符指针 s 指向的字符串中字符的个数&#xff0c;不包括’\0’ 返回值&#xff1a;字符串中字符个数 #include <stdio.…