1. Mysql InnoDB中的索引

news2024/11/17 9:40:34

一、InnoDB中的索引

InnoDB存储引擎支持以下几种常见的索引:B+树索引、全文索引、哈希索引,其中比较关键的是B+树索引。

1. B+树索引介绍

InnoDB中的索引自然也是按照B+树来组织的,前面我们说过B+树的叶子节点是用来放数据的。但是放什么数据呢?索引肯定是要放的。因为B+树的作用本来就是为了快速检索数据而提出的一种数据结构。索引是怎么放的呢?
数据库中的数据才是我们需要的。索引只是一个辅助数据,甚至于一个表可以没有自定义索引。InnoDB中的数据是如何组织的呢?

1.1 聚集索引 / 聚簇索引

InnoDB中使用了聚集索引,就是将表的主键用来构建一颗B+树并且将整张表的行记录数据存放在 B+树的叶子节点中。也就是所谓的索引即数据,数据既索引。由于聚集索引是利用表的主键构建的,所以每张表,只能拥有一个聚集索引

聚集索引的叶子节点就是数据页,换句话说,数据页上存放的是完整的每行记录。因此聚集索引的一个优点是:通过聚集索引能获取完整的整行数据。另一个优点是:对于主键的排序查找和范围查找速度非常的快。

1.1.1 聚集索引 / 聚簇索引 的创建

下面是我们数据表的结构:
其中我们指定了 id 是一个主键(聚集索引)

ps:我们下面操作数据库,都是以这个表进行操作的。
在这里插入图片描述

数据表里面的数据
在这里插入图片描述

当指定一个主键后,并且在表里面添加数据后,B+树的结构如下:
在这里插入图片描述
如果我们在创建数据表的时候,没有定义主键的话。MySql会使用唯一性索引。没有唯一性索引,mysql会创建一个隐含的列RowId来做主键,然后用这个主键来建立聚集索引。



聚集索引只能在搜索条件是主键的时候才能发挥作用,因为B+树中的数据都是按照主键进行排序的。

如果我们想以别的列作为搜索条件怎么办?我们一般会建立多个索引,这些索引被称为辅助索引 / 二级索引。

每建立一个索引,就有一颗B+树,一个索引就是一颗B+树

1.2 辅助索引 / 二级索引

辅助索引(Secondary Index,也称二级索引、非聚集索引) 。

叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签(bookmark)。该书签用来告诉InnoDB存储引擎,哪里可以找到与当前索引相对应的行数据。因此InnoDB存储引擎的辅助索引的书签就是相应行数据的聚集索引键(就是主键)

1.2.1 辅助索引 / 二级索引 的创建

我们为username列创建辅助索引

CREATE INDEX user_index_username ON user_info (username);

索引创建的格式

使用CREATE INDEX创建,语法为:
indexName:索引的名称
tableName:表的名称
columnName:列的名称
CREATE INDEX indexName ON tableName (columnName);

这是我们创建的索引:
在这里插入图片描述
我们是用 username列创建的辅助索引,那么B+树的叶子节点就是这个样子:
在这里插入图片描述
二级索引下面对应的就是当前列的聚集索引。

1.3 回表

辅助索引的存在并不影响数据在聚集索引中的组织。因此每个表上可以有多个辅助索引。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶子节点的指针指向主键索引的主键。然后再通过主键索引(聚集索引)来找到一个完整的记录。这个过程也被称为 回表。也就是根据辅助索引的值查询一条完整的用户记录需要使用 2颗B+树(一次辅助索引,一次聚集索引)。

B+树结构图:
在这里插入图片描述
为什么我们还需要一次回表操作呢?直接把完整的用户记录放到辅助索引的叶子节点上不就好了吗?

如果把完整的用户记录放到叶子节点是可以不用回表的。数据量小倒还好,如果几百万几千万数据。是不是太浪费磁盘空间了?
每建立一颗B+树都需要把所有的用户记录拷贝一遍,而且每次对数据的变化要在所有包含数据的索引中全部都修改一次,性能也非常低下。

很明显,回表的记录越少,性能提升就越高,需要回表的记录越多,使用二级索引的性能就越低,甚至让某些查询宁愿使用全表扫描也不愿意使用二级索引。

那时候时候采用全表扫描的方式?什么时候使用二级索引+回表的方式去执行呢?这个就是查询优化器的工作了,查询优化器回事先对表中的记录算一些统计数据,然后再利用这些统计数据根据查询的条件来计算一下回表的次数。需要回表的记录越多,就越倾向于使用全表扫描,反之倾向使用二级索引+ 回表的方式。这个我们后面会讲到的。我们先来讲索引。

1.4 联合索引 / 复合索引

前面我们对索引的描述,隐含了一个条件,那就是构建索引的字段只有一个,但实践工作中构建索引的完全可以是多个字段。所以,将表上的多个列组合起来进行索引,我们称之为联合索引(复合索引)。

注意一点,建立联合索引只会建立 一颗B+树 ,多个列分别建立索引,则会分别以每个列建立 一颗B+树,有几个列就是有几颗B+树,比如,index(username),index(status) 就是分别对 username、status两个列构建了 2个B+树。

1.4.1联合索引 / 复合索引 的创建

create index user_index_username_status_create on  user_info(username,status,create_time)

联合索引创建的格式

使用CREATE INDEX创建,语法为:
indexName:索引的名称
tableName:表的名称
columnName:多个列以逗号隔开 ,
CREATE INDEX indexName ON tableName (columnName);

B+树的创建规则如下:

  1. 先把第一个索引进行排序 就是 username
  2. 在记录username列相同(这里的相同指的是里面的数据)的情况下,采用status进行排序。
    在这里插入图片描述
    这个就是类似B+树组合索引的结构。最后的指针还是指向聚集索引里面的值。
    从上面可以看到,他是以第一个列来创建索引的。如果我跳过第一个列去进行查询,会走索引吗?

1.4 覆盖索引

既然多个列可以组合成联合索引,那么辅助索引自然也可以由多个列组成。

InnoDB存储引擎支持覆盖索引(coving index,或称索引覆盖),既从辅助索引中就可以得到查询的记录。而不需要查询聚集索引中的记录(回表),使用覆盖索引的一个好处是辅助索引不包含整行记录的所有信息,故其大小要要远小于聚集索引,因此可以减少大量的IO操作。所以谨记。
覆盖索引并不是索引类型的一种。
在这里插入图片描述
其实覆盖索引就是,不要去查询其他列,就查询你联合索引里面的列,或者辅助索引里面的列,不要让他去发生 回表操作。

2. 哈希索引

InnoDB存储引擎除了我们前面所说的各种索引,还有一种自适应哈希索引,我们知道B+树的查找次数,取决于B+树的高度,在生产环境中,B+树的高度一般为3、4层 (B+树的高度只能去估算,3层大约在2000万数据量级别,再往上要考虑分库分表了)。故需要3、4次的IO查询。

所以在InnoDB存储引擎内部自己去监控索引表,如果监控到某个索引经常使用,那么就认为这个索引是个 热数据,然后内部为这个热数据创建一个hash索引,称为自适应哈希索引(Adaptive Hash Index,AHI),创建以后,如果下次又查询到这个索引,那么直接通过hash算法推导出记录的地址。直接一次就能查到数据。比重复去B+树查询3-4个节点的效率高了不少。

InnoDB存储引擎使用的哈希函数采用除法散列方式,其冲突机制采用链表方式。注意,对于自适应哈希索引仅是数据库自然创建并使用的,我们并不能干预。

查看是否开启自适应哈希索引

show engine innodb status

在这里插入图片描述
哈希值只能用来搜索等值的查询,如

SELECT * FROM table WHERE index co=xxx

而对于其他类型,如范围查找,是不能使用哈希索引的。

3. 全文索引

什么是全文检索(Full-Text Search)?它是将存储于数据库中的整本书或整篇文章中的任意内容信息查找出来的技术。它可以根据需要获得全文中有关章、节、段、句、词等信息,也可以进行各种统计和分析。我们比较熟知的Elasticsearch、Solr等就是全文检索引擎,底层都是基于Apache Lucene的。

举个例子,现在我们要保存唐宋诗词,数据库中我们们会怎么设计?诗词表我们可能的设计如下:

朝代作者诗词年代标题诗词全文
李白静夜思床前明月光,疑是地上霜。 举头望明月,低头思故乡。
李清照如梦令常记溪亭日暮,沉醉不知归路,兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
….….….…….

要根据朝代或者作者寻找诗,都很简单,比如“select 诗词全文 from 诗词表 where作者=‘李白’”,如果数据很多,查询速度很慢,怎么办?我们可以在对应的查询字段上建立索引加速查询。

但是如果我们现在有个需求:要求找到包含“望”字的诗词怎么办?用

“select 诗词全文 from 诗词表 where诗词全文 like‘%望%’”,这个意味着要扫描库中的诗词全文字段,逐条比对,找出所有包含关键词“望”字的记录,。基本上,数据库中一般的SQL优化手段都是用不上的。数量少,大概性能还能接受,如果数据量稍微大点,就完全无法接受了,更何况在互联网这种海量数据的情况下呢?怎么解决这个问题呢,用倒排索引。

倒排索引就是,将文档中包含的关键字全部提取处理,然后再将关键字和文档之间的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一个关键字是,先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。

于是我们可以这么保存

序号关键字蜀道难静夜思春台望鹤冲天
1

如果查哪个诗词中包含上,怎么办,上述的表格可以继续填入新的记录

序号关键字蜀道难静夜思春台望鹤冲天
1
2

从InnoDB 1.2.x版本开始,InnoDB存储引擎开始支持全文检索,对应的MySQL版本是5.6.x系列。不过MySQL从设计之初就是关系型数据库,存储引擎虽然支持全文检索,整体架构上对全文检索支持并不好而且限制很多,比如每张表只能有一个全文检索的索引,不支持没有单词界定符( delimiter)的语言,如中文、日语、韩语等。

所以MySQL中的全文索引功能比较弱鸡,了解即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻防世界-基础android

下载链接:下载 参考链接:攻防世界-Mobile-基础android (Misc经验解法)_攻防世界基础android_Q_yt的博客-CSDN博客 方法一: 这是个偏向Misc的解题思路,下载完是个apk文件,载入010 Editor看一下&#xff0…

京东工作8年,肝到T8就剩这份心得了,已助朋友拿到10个Offer

在京东工作了8年,工作压力大,节奏快,但是从技术上确实得到了成长,尤其是当你维护与大促相关的系统的时候,熬到T7也费了不少心思,小编也是个爱学习的人,把这几年的工作经验整理成了一份完整的笔记…

TiDB亿级数据亚秒响应查询方案介绍

目录 1 什么是TiDB2 什么是NewSQL2.1 传统SQL的问题2.1.1 升级服务器硬件2.1.2 数据分片 2.2 NoSQL 的问题2.2.1 优点2.2.2 缺点 2.3 NewSQL 特性2.3.1 NewSQL 的主要特性:2.4 三种SQL的对比 3 TiDB怎么来的3.1 TiDB社区版和企业版 4 TIDB核心特性4.1 水平弹性扩展4…

【JUnit技术专题】「入门到精通系列」手把手+零基础带你玩转单元测试,让你的代码更加“强壮”(核心API篇)

手把手零基础带你玩转单元测试,让你的代码更加“强壮”(核心API篇) JUnit 中的重要的 APIAssert 类TestCase 类TestResult 类TestSuite 类 JUnit 中的重要的 API JUnit 中的最重要的程序包是 junit.framework 它包含了所有的核心类。一些重要…

数字孪生:数字世界与现实世界的交汇

数字孪生是一种崭新的技术,指将现实世界中的物理实体、系统或过程通过数字化技术在虚拟数字世界中建立起虚拟模型。数字孪生可以帮助人们以更小的成本地理解和预测现实世界中的物理实体、系统或过程的行为和性能,从而提高生产效率、降低成本、减少风险等。 如今数字孪生技术…

Makerbase SimpleFOC ESP32 例程1 双电机开环速度测试

Makerbase SimpleFOC ESP32 例程1 双电机开环速度测试 第一部分 硬件介绍 1.1 硬件清单 序号品名数量1ESP32 FOC V1.0 主板12YT2804电机2312V电源适配器14USB 线1 注意:YT2804是改装的云台无刷电机,带有AS5600编码器,可实现360连续运转。 主要参数如…

刷题记录:双指针 | leetcode-1156. 单字符重复子串的最大长度 2023/6/3

1156. 单字符重复子串的最大长度 感觉这道题,双指针的思路很好想,但是要直接实现,对我而言还是有一些磕磕绊绊(还是题做少了qaq)。 思路是这样的,比如字符串序列为: aaabaaaba 那么一开始&am…

【leetcode】1156. 单字符重复子串的最大长度

1156. 单字符重复子串的最大长度 问题描述问题分析解决方案 问题描述 1156. 单字符重复子串的最大长度 如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。 给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做&#xff…

基于AT89C52单片机的液晶多功能电子台历设计

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87858426 源码获取 第5章 液晶多功能电子台历的设计 5.1 功能要求 该项目以单片机STC89C54为核心,结合单线数字温度传感器DS18B20、时钟芯片DS1302和液晶显示器12864设计而…

GPU推理和端侧NPU推理的一处不同

端侧AI推理主要使用NPU完成,为了在性能,功耗和面积和通用性之间取得平衡,主流NPU采用了加速器架构,将算子固化在硬件中,并辅以可编程单元执行一些自定义算子/长尾算子兼顾灵活性。在计算方面,为了提高存储使用效率和加速计算,在满足计算精度的前提下,NPU普遍采用定点计…

编程的未来 - 还有未来么?

缘起 唐门教主上个月某天深夜写了一篇博客 --《编程的未来》,要我谈谈感想。 这也是最近软件工程师们聊得比较多的问题,上周,在上海的 “关东小磨” 和十多位 CSDN 博主聚会的时候,大家也稍微谈了一下这个话题,但是谈…

一哥们从小厂逆袭,涨薪50%,真是麻雀啄了牛屁股,雀食牛逼啊

前言 大多数情况下,软件测试人员的个人技能成长速度,远远大于公司规模或业务的成长速度。所以,跳槽成为了这个行业里最常见的一个词汇。 实际上,跳槽的目的无非是为了涨薪或是职业发展,我也不例外。普通本科毕业后&a…

vscode课程学习分析选课作业系统nodejs+vue

软件体系结构方案:由于本系统需要在不同设备上都能运行,而且电脑配置要求也要越低越好,为了实现这一要求,经过考虑B/S结构成为最佳之选。使用B/S结构的系统可以几乎在任何电脑上运行,只要浏览器可以正常工作就可以正常…

操作系统复习5.1.0-I/O管理

分类 按使用特性分 人机交互类:键盘、鼠标、打印机 存储设备:移动硬盘、光盘 网络通信设备:调制解调器 按速率分 低速设备:键鼠 中速设备:打印机 高速设备:磁盘 按信息交换单位分 块设备:…

yum和vim【Linux操作系统】

Linux软件包管理器 yum Linux安装软件: 源代码安装(下载到程序的源代码,进行编译,得到可执行程序,太麻烦,因此有些人会将有些常用的软件提前编写好,做成软件包) rpm安装(…

BCD格式及与十进制/十六进制的转换

本文框架 前言1. BCD码是什么?2. 不同进制与BCD码之间的转换2.1 十进制与BCD码的转换2.1.1 十进制转换为BCD码2.1.2 BCD码转换为十进制 2.2 十六进制与BCD码的转换 前言 在诊断快照开发中会遇到保存年月日等使用BCD码格式的需求,本篇我们就一起看一下BC…

Sentinel监控微服务_流量控制_熔断降级_系统规则讲解

Sentinel 监控微服务 需求分析/图解 需求: 使用Sentinel 控制台对member-service-nacos-provider-10004 微服务进行实时监控 示意图 当调用了member-service-nacos-provider-10004 微服务时, 可以监控到请求的url/QPS/响应时间/流量 代码/配置实现 修改member-service-nac…

Redis之SDS数据结构的使用

目录 序言字符串 char*字符串数组简单动态字符串SDS 序言 Redis的几种基本数据结构有字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set&…

美国原装二手KEYSIGHT N8975A是德N8975B噪声系数分析仪

KEYSIGHT / AGILENT N8975A N8975B 噪声系数分析仪 Keysight N8975B 高性能噪声系数分析仪旨在进行快速、准确和可重复的噪声系数测量。它有一个多点触控界面,允许拉伸、捏合和拖动手势。大多数菜单都可以通过手指轻点来访问,而无需切换屏幕。通过允许…

【数据结构】第10周

目录 1.图的基本术语 2.图的存储 2.1邻接矩阵 2.2.邻接表 3.图的遍历 3.1 深度搜索 dfs 3.2 广度搜索 bfs 4.图的应用 4.1 最小生成树 4.1.1 普里姆算法 4.1.2 克鲁斯卡尔算法 4.2 最短路径 4.2.1 Dijkstra算法 4.2.2 Floyd算法 4.3 拓扑排序 4.4 关键路径 一些…