当前位置: 首页 > news >正文

【MySQL】B+ 树索引

一、索引是什么 ? 为什么需要索引 ?

索引就是目录,目录就是索引。

索引从 InnoDB 存储引擎数据存储结构上来看,就是为各个页建立的目录。保证我们在查询时,可以通过二分法快速定位到页,再在页内通过二分法快速定位到组,再在组内进行查询。

背景知识:页分裂表示进行创建新页存放我们插入的数据的过程要求创建完的这些页中的记录具有主键值的递增关系。

二、为页建立的目录应该什么样子 —— 如何设计

为页建立目录,目录的目录项为 :

  • 用户记录中最小的主键值
  • 页号

1. 为页建立的目录也被封装成页了 —— 成了索引

因为 InnoDB 以页为单位,所以我们上面说的为页建立的目录也需要被放在一个页里。这个页就是目录项页,目录项页中的记录就是把目录项封装为记录,即目录页中的记录为 (页号, 用户记录中最小的主键值)

目录项记录和我们的数据页中的记录具有如下区别:

  1. 标志记录类型的值不同 —— 目录项记录的 record_type = 1, 普通用户记录为 0
  2. 记录的内容不同

2. 有了目录项页后的查找过程

  1. 在目录页中通过二分查找定位到所在的页
  2. 在所在页的页目录中通过二分查找进行查找

3. 目录项页也是个页,其存不下那么多目录项了咋办

新增新的目录项页就行了,然后再为这些目录项页抽象出一个目录项页的目录页 。 —— … 太厉害了 ~

然后我们就可以发现这个结构变成树了 —— 这个树就是 B+ 树, 就是我们 InnoDB 中的索引实现方式

然后我们再去想,我们的用户数据记录都在树的叶子节点(就是最下层),其他的目录的内容都在非叶子节点上 —— 这就是 B+ 树的特点

三、索引类型

1. 聚簇索引

我们上文说的 B+ 树就是个聚簇索引,它具有两个特点:

  1. 使用记录主键值进行排序
  2. B+ 树的叶子节点就是用户记录

InnoDB 会自动为我们创建聚簇索引,而且这个聚簇索引就是 InnoDB 的数据存储结构,嘿嘿嘿,一句非常好的话 —— 索引即数据,数据即索引

2. 二级索引

我们不可能一直通过主键进行查询,有时候也需要通过一些非主键的列进行查找。这时的索引的策略是对这个非主键列建立一颗 B+ 树(就是按照这个列进行排序建立二叉树),但是其 叶子节点 存放的值只有 : 索引列的值 + 主键值 + 页号 。 我们通过这个列得到要查找的记录的主键值,然后再拿着主键值进行回表 (就是再去聚簇索引那里查一遍),所以其需要遍历两棵 B+ 树,所以才叫 “二” 级索引鸭 ~~

注:为啥不全存上,为啥只存主键 id ,要是全存上不久不用回表了嘛 ? —— 空间 !! 空间 !!!

3. 联合索引

以多个列作为排序规则建立索引,本质上也是个二级索引

注: 排序方式为先按照第一个列,再按第二个列 …

四、用索引

1. 索引的缺点

占用空间 + 索引维护浪费时间

2. 什么情况下才使用到索引

背景: 创建索引 ——

  1. 在 创建表 时创建
key idx_rowname1_rowname2....(rowname1, rowname2, ....)
  1. 创建表之后,选择表创建
alter table table_name add key/index row_name

(1)情况一: 全值匹配

搜索条件的列和索引列一致,即我们建立了联合索引,然后我们的搜索条件刚刚好就是这个联合索引建立的列

注: 顺序没有影响, MySQL 的查询优化器会帮我们调整到最优顺序

(2)情况二: 匹配左面的列

联合索引中的列可以不全用到,只包含左面(一个或者多个列)就行 (理解联合索引的排序方式很重要 !!!)

联合索引的后面的列可以没有,可以不用,下面举个例子

用户记录为 :(row1, row2, row3, row4),假如一个联合索引是这样的 row2_row3_row4

这种情况都可以用到索引 : .... where row2 = value1 and row3=value2 and row1=value3

这种情况下我们可以用到 row2_row3 的索引,然后再筛选出 row1

这种情况就用不到索引了 : .... where row3 = value 或者 ... where row4 = value 等等

(3)匹配列前缀原则

根据字符集的比较规则,对于字符串类型的索引,可以只匹配前缀

where row like 'Prefix%'

但是注意: 不可以匹配中缀,或者后缀,只能是前缀,这是由字符集的排序规则决定的

如果需要比较后缀,可以把字符串逆序存储 …

(4)情况四:匹配范围

因为我们的记录是按照索引的大小用链表连着的,所以可以取出范围,但是对多个索引列同时进行范围查找的话,只能用到最左面的那个索引列。理由很清晰:

只有当前索引值相同,才按下一个索引排序,而这个是个范围,对这个范围内的第一个索引下面的查找的那个索引列的值不一定啥样子,所以只能用到最左面的第一个索引列

(5)其他情况

这都是根据索引构造的原理决定的,还有如下情况也能用到索引:

  1. 精确匹配 + 范围匹配
  2. 排序情况
  3. 分组

补充: 什么情况下排序不能用到索引

排序列不在索引里、按多个列进行排序的列不包含在一个联合索引里、排序列包含了复杂的表达式

3. 到底要不要回表

我们平时进行非范围查询, 这时候我们只需要拿着在 二级索引 中找到的 id,回表一次 聚簇索引就 ok 了

但是但我们进行范围查询时,我们是拿着一堆 id , 等着要去回表, 这些 id 不挨着,做的是 随机 io ,非常损耗性能。 —— 这种情况宁可全表扫描,也不要回表一堆次聚簇索引。

当然是否回表是 MySQL 优化器决定的,其会根据回表次数自己判断是要回表还是全表扫描。

但是我们可以通过 覆盖索引 的方式彻底摆脱回表。所以我们尽量不要 select *

五、什么样子的列适合建立索引

  1. 搜索、排序、分组的列
  2. 不咋重复的列 —— 比如具有唯一值的列
  3. 数据类型占用空间小的列 —— 比如数字类型
  4. 对字符串值的前缀建立索引

六、注意事项

  1. 不要在查询中对索引列瞎做运算,让索引列单独存在,不然不要索引列,而是挨个运算
  2. 使用自增主键,降低维护聚簇索引的成本
  3. 不要瞎建立一堆冗余索引,用一个联合索引就能解决

相关文章:

【MySQL】B+ 树索引

一、索引是什么 ? 为什么需要索引 ? 索引就是目录,目录就是索引。 索引从 InnoDB 存储引擎数据存储结构上来看,就是为各个页建立的目录。保证我们在查询时,可以通过二分法快速定位到页,再在页内通过二分法…...

Android Gradle Plugin Version 和 Gradle Version 的对应关系

官网参考 以下是插件版本和Gradle 版本对应关系: 插件版本所需的最低 Gradle 版本Android Gradle Plugin VersionGradle Version1.0.0 - 1.1.32.2.1 - 2.31.2.0 - 1.3.12.2.1 - 2.91.5.02.2.1 - 2.132.0.0 - 2.1.22.10 - 2.132.1.3 - 2.2.32.14.1 - 3.52.3.03.33.0…...

更多单词/词组/短语补充和总结(二)

auto 美 /[ˈɔːtoʊ] n.汽车adj.与汽车有关的,汽车的。不要记成“自动的” mobile 美 /[ˈmoʊbl] adj.可移动的;流动的;不要记成“手机”,手机是mobile phone automobile 美 /[ˈɔːtəməbiːl] n.汽车adj.自动的 automatic 美 /[ˌɔːtəˈmtɪk]…...

HEC-HMS和HEC-RAS快速入门、防洪评价报告编制及洪水建模、洪水危险性评价等应用

目录 ①HEC-RAS一维、二维建模方法及实践技术应用 ②HEC-HMS水文模型实践技术应用 ③新导则下的防洪评价报告编制方法及洪水建模实践技术应用 ④基于ArcGIS水文分析、HEC-RAS模拟技术在洪水危险性及风险评估 ⑤山洪径流过程模拟及洪水危险性评价 ①HEC-RAS一维、二维建模方…...

全面了解 B 端产品设计 — 基础扫盲篇

在今天,互联网的影响力与作用与日俱增,除了我们日常生活领域的改变以外,对于商业领域的渗透也见效颇丰。 越来越多的企业开始使用数字化的解决方案来助力企业发展,包括日常管理、运营、统计等等。或者通过互联网的方式开发出新的业务形态,进行产业升级,如这几年风头正劲的…...

顺序表(增删查改)

目录一、什么是顺序表二、顺序表的增删查改2.1 结构体的声明2.2 顺序表的初始化2.3 顺序表检查容量2.4 顺序表尾部插入数据2.5 顺序表头部插入数据2.6 顺序表尾部删除数据2.7 顺序表头部删除数据2.8 顺序表查找数据2.9 顺序表任意位置插入数据2.10 顺序表任意位置删除数据2.11 …...

一款优秀的低代码开发平台是什么样的?

目录 一、一款优秀的低代码平台应该是什么样的? 二、低代码核心能力 01、全栈可视化编程: 02、全生命周期管理: 03、低代码扩展能力: 三、小结 一、一款优秀的低代码平台应该是什么样的? 从企业角度来说&#x…...

ElasticSearch 学习笔记总结(四)

文章目录一、ES继承 Spring Data 框架二、SpringData 功能集成三、ES SpringData 文档搜索四、ES 优化 硬件选择五、ES 优化 分片策略六、ES 优化 路由选择七、ES 优化 写入速度优化七、ES 优化 内存设置八、ES 优化 重要配置一、ES继承 Spring Data 框架 Spring Data 是一个用…...

HDFS文件块大小

HDFS中的文件在物理上是分块存储(Block),块的大小可以通过配置参数(dfs.blocksize)来规定,默认大小在Hadooop2X版本中是128M,老版本中是64M。 思考:为什么块的大小不能设置太小&…...

C++——优先级队列(priority_queue)的使用及实现

目录 一.priority_queue的使用 1.1、基本介绍 1.2、优先级队列的定义 1.3、基本操作(常见接口的使用) 1.4、重写仿函数支持自定义数据类型 二.priority_queue的模拟实现 2.1、构造&&重要的调整算法 2.2、常见接口的实现 push() pop() top() empt…...

Linux学习记录——십일 环境变量

文章目录1、认识2、通过代码获取环境变量1、手动获取2、函数获取3、重新认识环境变量1、认识 在云服务器上写程序时,最终的执行需要./文件名,点表示当前目录,/是文件分隔符,之后就会打印程序,这是用户的操作&#xff…...

【人工智能 Open AI 】我们程序员真的要下岗了- 全能写Go / C / Java / C++ / Python / JS 人工智能机器人

文章目录[toc]人工智能 AI Code 写代码测试用golang实现冒泡排序用golang实现计算环比函数goroutine and channel用golang实现二叉树遍历代码用golang实现线程安全的HashMap操作代码using C programming language write a tiny Operation Systemuse C language write a tiny co…...

STM32 EXTI外部中断

本文代码使用 HAL 库。 文章目录前言一、什么是外部中断?二、外部中断中断线三、STM32F103的引脚复用四、相关函数:总结前言 一、什么是外部中断? 外部中断 是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片…...

Mapper代理开发——书接MaBatis的简单使用

在这个mybatis的普通使用中依旧存在硬编码问题,虽然静态语句比原生jdbc都写更少了但是还是要写,Mapper就是用来解决原生方式中的硬编码还有简化后期执行SQL UserMapper是一个接口,里面有很多方法,都是一一和配置文件里面的sql语句的id名称所对…...

实体对象说明

1.工具类层Utilutil 工具顾明思义,util层就是存放工具类的地方,对于一些独立性很高的小功能,或重复性很高的代码片段,可以提取出来放到Util层中。2.数据层POJO对象(概念比较大) 包含了以下POJO plain ord…...

JAVA中加密与解密

BASE64加密/解密 Base64 编码会将字符串编码得到一个含有 A-Za-z0-9/ 的字符串。标准的 Base64 并不适合直接放在URL里传输,因为URL编码器会把标准 Base64 中的“/”和“”字符变为形如 “%XX” 的形式,而这些 “%” 号在存入数据库时还需要再进行转换&…...

改进YOLO系列 | ICLR2022 | OMNI-DIMENSIONAL DYNAMIC CONVOLUTION: 全维动态卷积

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…...

信息收集之Github搜索语法

信息收集之Github搜索语法1.Github的搜索语法2.使用 Github 进行邮件配置信息收集3.使用Github进行数据库信息收集4.使用Github进行 SVN 信息收集5.使用Github进行综合信息收集在测试的信息收集阶段,可以去Github和码云上搜索与目标有关的信息,或者就有意…...

【案例教程】拉格朗日粒子扩散模式FLEXPART

拉格朗日粒子扩散模式FLEXPART通过计算点、线、面或体积源释放的大量粒子的轨迹,来描述示踪物在大气中长距离、中尺度的传输、扩散、干湿沉降和辐射衰减等过程。该模式既可以通过时间的前向运算来模拟示踪物由源区向周围的扩散,也可以通过后向运算来确定…...

试题 算法训练 自行车停放

问题描述 有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。(e.g.停车棚里已经有3辆自行车,从左到右编号为:3,5,1。现在编号为2的第4辆自行车要停在5号自行车的左…...

泛型与Map接口

Java学习之道 泛型 泛型这种参数类型可以用在类、方法和接口中,分别被称为泛型类,泛型方法,泛型接口 参数化类型:将类型由原来的具体的类型参数化,在使用/调用时传入具体的类型JDK5引入特性提供了安全检测机制&#xf…...

Unity Bug记录本

//个人记录&#xff0c;持续更新 1、将此代码挂载到空脚本上&#xff1a; bool flag (object)GetComponent<Camera>() null; bool flag1 (object)GetComponent<Text>() null; Debug.Log(flag"::"flag1); //输出结果&#xff1a;False::True bool…...

B. The Number of Products)厉害

You are given a sequence a1,a2,…,ana1,a2,…,an consisting of nn non-zero integers (i.e. ai≠0ai≠0). You have to calculate two following values: the number of pairs of indices (l,r)(l,r) (l≤r)(l≤r) such that al⋅al1…ar−1⋅aral⋅al1…ar−1⋅ar is neg…...

一起Talk Android吧(第五百一十二回:自定义Dialog)

文章目录整体思路实现方法第一步第二步第三步第四步各位看官们大家好&#xff0c;上一回中咱们说的例子是"自定义Dialog主题",这一回中咱们说的例子是" 自定义Dialog"。闲话休提&#xff0c;言归正转&#xff0c; 让我们一起Talk Android吧&#xff01;整体…...

GinVueAdmin源码分析3-整合MySQL

目录文件结构数据库准备配置文件处理config.godb_list.gogorm_mysql.gosystem.go初始化数据库gorm.gogorm_mysql.go开始初始化测试数据库定义实体类 Userserviceapi开始测试&#xff01;文件结构 本文章将使用到上一节创建的 CommonService 接口&#xff0c;用于测试连接数据库…...

大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——MapReduce开发总结

在编写MapReduce程序时&#xff0c;需要考虑如下几个方面&#xff1a; 1、输入数据接口&#xff1a;InputFormat 默认使用的实现类是&#xff1a;TextInputFormatTextInputFormat的功能逻辑是&#xff1a;一次读一行文本&#xff0c;然后将该行的起始偏移量作为key&#xff0…...

requests---(4)发送post请求完成登录

前段时间写过一个通过cookies完成登录&#xff0c;今天我们写一篇通过post发送请求完成登录豆瓣网 模拟登录 1、首先找到豆瓣网的登录接口 打开豆瓣网站的登录接口&#xff0c;请求错误的账号密码&#xff0c;通过F12或者抓包工具找到登录接口 通过F12抓包获取到请求登录接口…...

Python抓取数据具体流程

之前看了一段有关爬虫的网课深有启发&#xff0c;于是自己也尝试着如如何过去爬虫百科“python”词条等相关页面的整个过程记录下来&#xff0c;方便后期其他人一起来学习。 抓取策略 确定目标&#xff1a;重要的是先确定需要抓取的网站具体的那些部分&#xff0c;下面实例是…...

【Python学习笔记】第二十四节 Python 正则表达式

一、正则表达式简介正则表达式&#xff08;regular expression&#xff09;是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。正则表达式是对字符串&#xff08;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特…...

数字逻辑基础:原码、反码、补码

时间紧、不理解可以只看这里的结论 正数的原码、反码、补码相同。等于真值对应的机器码。 负数的原码等于机器码&#xff0c;反码为原码的符号位不变&#xff0c;其余各位按位取反。补码为反码1。 三种码的出现是为了解决计算问题并简化电路结构。 在原码和反码中&#xff0c;存…...

做农产品的网站名称/产品推广ppt范例

点击上方“蓝色字”可关注我们&#xff01;暴走时评&#xff1a;尽管存在许多不明确法规和相应限制&#xff0c;但印度的大型企业和银行仍然采用加密货币 - 或至少是支持加密货币的一些技术 - 作为一种更可靠的方式来协调账户、付款、保存适当的记录和管理内部资金。根据“印度…...

展览设计制作公司/北京百度搜索排名优化

最常用的Eclipse的快捷键&#xff0c;各个实用&#xff0c;由Java攀登网提供。 虽然现在IDEA非常的好用&#xff0c;但是Eclipse还是有一定的受众用户&#xff0c;包括我现在的公司&#xff0c;领导就是让用Eclipse&#xff0c;因此喜欢Eclipse的朋友可以看下。 后面可以再讲…...

设计公司名字创意/上海优化seo

区块链技术被誉为第四次工业革命代表性成果之一&#xff0c;“最有潜力触发第五轮颠覆性革命浪潮的核心技术”&#xff0c;代表着互联网的未来&#xff0c;具有划时代意义。它被认为是与1975年的个人计算机、1993年的因特网同样具有革命性的信息技术突破。 日前&#xff0c;全…...

用wordpress好吗/黑龙江头条今日新闻

欢迎您戳蓝色字“工数平台”持续关注我们哟&#xff01;导言在当今中国的各个领域&#xff0c;“弯道超车”是个经常被提及的口号&#xff0c;然而常识和交规告诉我们&#xff0c;弯道不仅不能超车还得减速&#xff0c;超车极其危险。仔细解读“弯道超车”&#xff0c;其实还暗…...

网站如何做点击链接地址/网络推广网站排行榜

我正在尝试从电子表格中读取日期列和时间列.我可以从工作表中退出日期列,但不能退出时间列.例如,我的工作表将包含以下形式的行&#xff1a;约会时间11/2/2012 12:15:01我有以下代码来获取日期列&#xff1a;while(cellIterator.hasNext()) {HSSFCell cell (HSSFCell)cellIter…...

做网站有什么不好/crm管理系统

方法 转载于:https://www.cnblogs.com/sen068/p/5362695.html...