我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何实现MySQL的索引

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何实现MySQL的索引

MySQL中索引分三类:B+树索引、Hash索引、全文索引。InnoDB存储引擎中用的是B+树索引。要介绍B+树索引,不得不提二叉查找树、平衡二叉树和B树这三种数据结构。B+树是从它们三个演化来的。

二叉查找树:

图中为user表建立了一个二叉查找树的索引。节点中存储了键(key)和数据(data)。数据对应user表中的行数据。

如果查找id=12的用户信息,流程如下:
1)将根节点作为当前节点,12大于10,将10的右子节点(13节点)作为当前节点。
2)12与13比较,将13的左子节点(12节点)作为当前节点。
3)12与12比较,满足条件,从当前节点去除data,即id=12,name=xm。
利用二叉查找树,3次可找到匹配数据。如果在表中一条一条查找,需要6次。

平衡二叉树:

如果上面的二叉树这样构造:

变成了一个链表,查询id=17的用户信息,需要查7次,相当于全表扫描。导致这个现象是因为二叉查找树不平衡了。为了解决这个问题,需要用平衡二叉树。
平衡二叉树又称 AVL 树,在满足二叉查找树特性的基础上,要求每个节点的左右子树的高度差不能超过 1。

B树:
因为内存的易失性,一般会将数据和索引存储到磁盘中。和内存比,从磁盘读数据会慢很多,所以应当减少读取次数。此外,从磁盘读数据按照磁盘块来读取,而非一条一条的读。
如果我们能把尽可能多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。我们都知道平衡二叉树可是每个节点只存储一个键值和数据的。那说明什么?说明每个磁盘块仅仅存储一个键值和数据!那如果我们要存储海量的数据呢?
可以想象到二叉树的节点将会非常多,高度也会极其高,我们查找数据时也会进行很多次磁盘 IO,我们查找数据的效率将会极低!
为了解决平衡二叉树的这个弊端,我们应该寻找一种单个节点可以存储多个键值和数据的平衡树。也就是我们接下来要说的 B 树。

图中的每个节点称为页(就是磁盘块),在MySQL中数据读取的基本单位都是页。每个节点存储了更多的键值和数据。子节点的个数一般称为阶,上述图中B树为3阶B树。
查找id=28的用户信息,

流程如下:

  • 1)先找到根节点也就是页 1,判断 28 在键值 17 和 35 之间,那么我们根据页 1 中的指针 p2 找到页 3。
  • 2)将 28 和页 3 中的键值相比较,28 在 26 和 30 之间,我们根据页 3 中的指针 p2 找到页 8。
  • 3)将 28 和页 8 中的键值相比较,发现有匹配的键值 28,键值 28 对应的用户信息为(28,bv)。

B+树:

B+树是对B树的进化,其不同:

  • 1)B+树非叶子节点不存储数据,仅存储键值,B树则存储键值和数据(为什么这么做?数据库中页的大小是固定的,InnoDB中默认是16KB,如果不存数据,就可以存更多的键值,树的阶数会更大,树就会更矮胖,查找数据进行磁盘IO的次数就会减少,查询效率快)。一般根节点是常驻内存的。
  • 2)B+树索引的所有数据存储在叶子节点,而且数据是按照顺序排列的(使得范围查找、排序查找、分组查找及去重查找很简单,而B树因为数据分散在各个节点,实现这一点很不容易),B+树的叶子节点中的数据通过单向链表连接,各个页之间通过双向链表连接。

过上图可以看到,在 InnoDB 中,我们通过数据页之间通过双向链表连接以及叶子节点中数据之间通过单向链表连接的方式可以找到表中所有的数据。

在 MySQL 中,B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。

利用聚集索引查找数据:

现在假设我们要查找 id>=18 并且 id<40 的用户数据。

对应的 sql 语句为:

select * from user where id>=18 and id<40;

其中id为主键,具体的查找过程如下:

  • 1)一般根节点常驻内存的,页1已经在内存中了,不用读磁盘,直接内存读取。
  • 在内存中页1查找id>=18 and id<40或者范围值,先找到id=18的键值。从页1找到指针p2,定位到页3。
  • 2)从磁盘中读取页3,然后将页3放入内存中,然后进行查找,可以找到键值18,然后拿到页3中的指针p1,定位到页8。
  • 3)将页8读取到内存中,根据二分查找法定位到键值18, 因为是范围查找,而且此时所有的数据又都存在叶子节点,并且是有序排列的,那么我们就可以对页 8 中的键值依次进行遍历查找并匹配满足条件的数据。
  • 我们可以一直找到键值为 22 的数据,然后页 8 中就没有数据了,此时我们需要拿着页 8 中的 p 指针去读取页 9 中的数据。
  • 4)因为页 9 不在内存中,就又会加载页 9 到内存中,并通过和页 8 中一样的方式进行数据的查找,直到将页 12 加载到内存中,发现 41 大于 40,此时不满足条件。那么查找到此终止。

具体流程图:

利用非聚集索引查找数据:

查找幸运数字为33的用户信息,需要回表。

到此这篇关于如何实现MySQL的索引的文章就介绍到这了,更多相关实现MySQL的索引内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何实现MySQL的索引

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Mysql索引覆盖如何实现

这篇“Mysql索引覆盖如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Mysql索引覆盖如何实现”文章吧。1.什么是
2023-07-05

mysql索引结构如何实现

mysql索引结构由b+树和哈希表组成,它们共同实现数据的高效检索和更新:1. b+树通过多级、平衡的结构按顺序存储数据,提供快速的数据访问;2. 哈希表使用哈希函数快速查找索引信息。MySQL 索引结构的实现MySQL 索引结构是存储和
mysql索引结构如何实现
2024-06-14

mysql的联合索引(复合索引)的实现

联合索引 本文中联合索引的定义为(MySQL):ALTER TABLE `table_name` ADD INDEX (`col1`,`col2`,`col3`);联合索引的优点 若多个一条SQL,需要多个用到两个条件SELECT * FR
2022-05-29

如何实现MySQL中创建索引的语句?

MySQL索引是提高数据检索速度的重要手段之一,它通过将数据存储在特定的数据结构中,加快了查询语句的执行速度。在MySQL中创建索引的语句非常简单,只需要在创建表的时候在相关字段后加上索引关键字即可。本文将为读者详细介绍如何在MySQL中创
如何实现MySQL中创建索引的语句?
2023-11-08

如何实现MySQL中删除索引的语句?

如何实现MySQL中删除索引的语句?在MySQL中,索引是提高查询性能的重要工具之一。然而,有时候我们需要删除某个表的索引,可能是因为索引不再使用或者需要重新设计。本文将介绍如何在MySQL中删除索引的语句,并给出具体的代码示例。在MySQ
如何实现MySQL中删除索引的语句?
2023-11-08

Mysql索引覆盖的实现

目录1.什么是覆盖索引2.覆盖索引为什么快3.SQL优化场景(1)无where条件(2)where条件区分度低(3)查询仅选择主键4.总结与建议1.什么是覆盖索引通常情况下,我们创建索引的时候只关注where条件,不过这只是索引优化的一个
2023-03-03

mysql索引的实现方式

mysql 索引通过 b+ 树(平衡的多路搜索树)、哈希表(基于键值对的快速查找)和哈希索引变体(前缀哈希)实现,用于支持主键、唯一索引、普通索引、等值查询、范围查询、模糊搜索、全文搜索和空间数据搜索。选择合适的索引类型取决于数据的性质和查
mysql索引的实现方式
2024-08-01

MySql如何查看索引并实现优化

mysql中支持hash和btree索引。innodb和myisam只支持btree索引,而memory和heap存储引擎可以支持hash和btree索引 我们可以通过下面语句查询当前索引使用情况:show status like '%Ha
2022-05-28

MySQL主键索引和非主键索引的实现

目录主键索引(Primary Key Index):非主键索引(Secondary Index):在jsmysql中,主键索引和非主键索引有不同的作用和特点:主键索引(Pjavascriptrimary Key Index):主键索引是
2023-10-27

MYSQL大表加索引的实现

起因是这样的,ZclOBGWDG有一张表存在慢sql,查询耗时最多达到12s,定位问题后发现是由于全表扫描导致,需要对字段增加索引,但是表的数据量600多万有些大,网上很多都说对大表增加索引可能会导致锁表,查阅了一些资料,可以说网上说了很多
2023-05-30

MySQL中聚簇索引与非聚簇索引的实现

目录基本概念和作用说明聚簇索引非聚簇索引示例一:创建索引示例二:索引的选择示例三:索引的维护示例四:索引与性能http://www.lsjlt.com优化示例五:索引的限制结论与讨论引发点在mysql数据库中,索引是提高查询性能的关键工具。
MySQL中聚簇索引与非聚簇索引的实现
2024-09-18

mysql如何加索引

如何为 mysql 表格添加索引MySQL 索引是一种数据结构,它可以提高查询性能。它通过对数据列进行排序和分组,从而减少了数据库在执行查询时需要扫描的行数。添加索引的步骤:确定要索引的列:选择经常用于查询的列,尤其是那些用于过滤或排序
mysql如何加索引
2024-06-12

Numpy布尔索引如何实现

本篇内容介绍了“Numpy布尔索引如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!布尔数据:只有两种值,即真(True)或假(Fals
2023-07-05

编程热搜

目录