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

mysql索引内部实现与算法分析

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

北京

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

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

看不清楚,换张图片

免费获取短信验证码

mysql索引内部实现与算法分析

本篇内容主要讲解“mysql索引内部实现与算法分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql索引内部实现与算法分析”吧!

存储引擎从索引的根节点开始进行搜索,通过节点槽中的指针向下层查找,比较节点页的值和要查找的值找到合适的指针进入下层子节点。存储引擎最终要么找到对应的值,要么该记录不存在。

叶子节点的指针指向的是被索引的数据,而不是其他的节点页
索引可以按值查找之外,还可以用于查询中的order by操作(原因:索引树中的节点是有序的)
B+tree索引的限制:

    1.如果不是按照索引的最左列开始查找,则无法使用索引

    2.不能跳过索引中的列

    3.如果查询中有某个列的范围查找,则其右边所有列都无法使用索引优化查找

B+树的插入操作

B+树的插入必须保证插入后叶节点中的记录依然排序,

插入B+树的三种情况

第一种情况,往图中插入28,leaf page和index page都没有满,直接插入

第二种情况,往图中插入70,leaf page满了,index page没有满

说明:采用旋转操作使得其减少一次页的拆分操作

第三种情况,在图中插入95,leaf page和index page都满了

说明:B+树为了保持平衡,对新插入的键值可能需要大量的拆分页操作,但是B+树主要用于磁盘,我们应该尽可能减少页的拆分,可以通过旋转功能(leaf page已经满了,但是左右兄弟节点没有满)


B+树的删除操作

B+树使用填充因子来控制树的删除变化,50%是填充因子可设的最小资。同样必须保证删除后叶节点中的记录依然排序。

删除B+树(根据填充因子的变化来衡量)的三种情况

在图中删除70

在图中删除25,此时25的兄弟节点的28更新到page index中

在图中删除60,此时填充因子小于50%,需要做合并操作

B+树索引

B+树索引本质是在B+树在数据库中的实现 特点:扇出性

数据库中B+树索引分为:聚集索引(clustered index)、辅助聚集索引(secondary index)

索引组织表:表中数据按照主键顺序存放

堆表:按照插入数据顺序存放,堆表上的索引都是非聚集的,且堆表没有主键

    聚集索引(每张表只有一个):按照每张表的主键构造一棵B+树,且叶节点存放着整张表的行记录数据,所以聚集索引的叶节点也成了数据页,

    辅助聚集索引的叶节点上存放的仅仅是键值以及指向数据页的偏移量,不是一个完整行记录
聚集索引不是一种单独的索引类型,而是一种数据存储方式。innodb的聚集索引实际上在同一个结构中保存了B+tree索引和数据行。

当表有聚集索引时,数据行实际上是存储在索引的叶子页中

说明:聚集索引的存储在物理上是不连续的,在逻辑上是连续的:1.页通过双向链表链接,页按照主键的顺序排序;2.每个页中的记录也是通过双向链表进行维护,物理存储上可以同样不按照主键存储

聚集索引的优点:

    可以把相关数据保存在一起

    数据访问更快(聚集索引将索引和数据保存在同一个b+tree中)

    使用覆盖索引扫描的查询可以直接使用页节点中的主键值

聚集索引的缺点:

    聚集数据提高了IO性能,如果数据全部放在内存中,则访问的顺序就没那么重要了

    插入速度严重依赖插入顺序。按主键的顺序插入是速度最快的。但如果不是按照主键顺序加载数据,则需在加载完成后最好使用optimize table重新组织一下表

    更新聚集索引列的代价很高。因为会强制innod将每个被更新的行移动到新的位置

    基于聚集索引的表在插入新行,或主键被更新导致需要移动行的时候,可能面临页分裂的问题。页分裂会导致表占用更多的磁盘空间。

    聚集索引可能导致全表扫描变慢,尤其是行比较稀疏,或由于页分裂导致数据存储不连续的时

    非聚集索引比想象的更大,因为二级索引的叶子节点包含了引用行的主键列

    非聚集索引访问需要两次索引查找(非聚集索引中叶子节点保存的行指针指向的是行的主键值),对于innodb自适应哈希索引可以减少这样的重复工作

辅助索引:叶节点包含键值,且每个叶级别的索引行还包含一个书签(相应行数据的聚集索引)

辅助索引和聚集索引的关系图

说明:辅助索引的存在不影响数据在聚集索引中的组织,所以每张表可以有多个辅助索引

原理:通过辅助索引来寻找数据时过程:innodb会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后再通过主键索引来找到一个完整的行记录。

B+树索引的管理

索引的创建和删除的方法:alter table;create /drop   index

创建主键索引过程:先创建一张新的临时表,然后将数据导入临时表,删除原表,再把临时表重名为原来的表名

创建辅助索引过程:在创建过程中不需要重建表,只会对表加上一个S锁,速度极快。

通过show index from table_name可以查看表中索引的信息

说明:

    table:索引所在的表名

    Non_unique:非唯一索引,primary key是0

    Key_name:索引的名称

    Seq_in_index:索引中该列的位置

    Column_name:索引的列

    Collation:列以什么方式存储在索引中,B+树索引总是A,即排序;如果使用了heap存储引擎,且建立了hash索引,就会显示NULL,因为hash通过hash桶来存放索引数据,而不是对数据进行排序

    Cardinality:表示索引中唯一值的数目的估计值,Cardinality/表的行数  尽可能接近1,太小则需要重建该索引

    Sub_part:是否是列的部分被索引,如只索引某一列的前多少字符,如果索引整个列,则该字段为NULL

    packed:关键字如何被压缩。没有被压缩则为NULL

    NULL:是否索引的列含有null值,

    Index_type:索引的类型,innodb只支持B+索引

    comment:注释

B+树索引的使用

当访问高选择性字段并从表中取出很少一部分行时,就需要对这个字段添加B+树索引

注:当取出数据量超过表中数据的20%,优化器就不会使用索引,而是进行全表的扫表。且预估的返回行数的值是不准确的

顺序读、随机读、预读取

    顺序读(sequntial read):顺序地读取磁盘上的块(block)

    随机读(random read):访问的块不是连续的,需要磁盘的磁头不断移动

    预读取(read ahead):通过一次IO请求将多个页预读取到缓冲池中

    随机预读取(random read ahead):当一个区(64个连续页)中13个页也在缓冲区中,并在LRU列表的前端(即页是被频繁访问),则innodb会将这个区剩余的所有页预读到缓冲区

    线性预读取(linear read ahead):基于缓冲池中页的模式,而不是数量。如果一个区中的24个页都被顺序访问了,则innodb会读取下一个区的所有页

innodb_read_ahead_threshold参数:表示一个区中的多少页被顺序访问时,innodb才启用预读取。默认值为56,即当一个区中的56个页被顺序访问时,则预读取下个区的所有页

联合索引:还是一棵B+树,不同的是联合索引的键值的数量不是1,而是大于等于2

哈希算法

自适应哈希索引使用的是散列表(hash table)的数据结构

哈希表(散列表):由直接寻址表改进而来

哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效

原理:对每一行数据,存储引擎会对所有的索引列计算一个哈希码(很小且不同键值的行计算出的哈希码也不一样),哈希索引将所有哈希码存储在索引中,同时也保存着每个数据行的指针。如果多个列的哈希值相同,索引会以链表的方式存放多个记录指针到同一个哈希条目中

在mysql中,只有memory引擎显示支持哈希索引(注:为非唯一哈希索引),NDB支持唯一哈希索引,innodb支持自适应哈希索引

哈希索引的限制:

    1.哈希索引只包含哈希值和行指针,而不存储字段值,索引不能使用索引的值来避免读取行

    2.哈希索引数据并不是按照索引值顺序存储的,所以无法用于排序

    3.哈希索引不支持部分索引匹配查找(因为哈希索引始终是使用索引列的全部内容来计算哈希值的)

    4.哈希索引只支持等值查询,包括= ,in

    5.当出现哈希冲突(不同的索引列值却有相同的哈希值)时,存储引擎必须遍历链表中所有的行指针,逐个比较直至找到符合条件的行

    6.如果哈希冲突很多,则索引维护操作的代价会很高(要避免哈希冲突,必须在where条件中带入哈希值和对应列值)。

自适应哈希索引

通过Innodb_adaptive_hash_index参数可以开启自适应哈希索引,数据库启动时会自动创建槽数为innodb_buffer_pool_size/256个哈希表

可以通过show engine innodb status查看当前自适应哈希索引的使用状况

说明:包括哈希索引的大小,使用情况,每秒使用自适应哈希索引搜索的情况

注:哈希索引只能用来搜索等值的查询,其他类型不能使用哈希索引

到此,相信大家对“mysql索引内部实现与算法分析”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

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

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

mysql索引内部实现与算法分析

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

下载Word文档

猜你喜欢

mysql索引原理与用法实例分析

本文实例讲述了mysql索引原理与用法。分享给大家供大家参考,具体如下: 本文内容:什么是索引创建索引普通索引唯一索引全文索引单列索引多列索引查看索引删除索引首发日期:2018-04-14什么是索引:索引可以帮助快速查找数据而基本上索引都要
2022-05-29

Mysql Innodb存储引擎之索引与算法的示例分析

这篇文章将为大家详细讲解有关Mysql Innodb存储引擎之索引与算法的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、概述索引太少,查询效率低;索引太多程序性能受到影响,索引的使用应该贴合实
2023-06-29

Mysql索引类型与基本用法实例分析

本文实例讲述了Mysql索引类型与基本用法。分享给大家供大家参考,具体如下: 索引 MySQL目前主要有以下几种索引类型:普通索引唯一索引主键索引组合索引全文索引- 普通索引 是最基本的索引,它没有任何限制。CREATE INDEX Ind
2022-05-17

Java分治法与二分搜索算法实例分析

本文实例讲述了Java分治法与二分搜索算法。分享给大家供大家参考,具体如下:1、分治法分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将各子问题的解合并得到原问题的
2023-05-30

java内部类引用局部变量与外部类成员变量实例分析

这篇“java内部类引用局部变量与外部类成员变量实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“java内部类引用局部
2023-06-17

从创建索引过程中内存变化来看SQL Server与MySQL的内存淘汰算法

在sqlserver中,几年之前就注意到一个现象:sqlserver中对一个大表创建索引或者rebuild索引的过程中,会引起内存剧烈的动荡,究其原因为何,这种现象到底正不正常,是不是sqlserver内存管理存在缺陷?另外,最近刚好想到跟MySQL对比一下类
从创建索引过程中内存变化来看SQL Server与MySQL的内存淘汰算法
2019-06-16

Java中的排序数索引怎么利用分治算法实现

Java中的排序数索引怎么利用分治算法实现?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体如下:/** * Find the first q and return the
2023-05-31

Python实现的堆排序算法原理与用法实例分析

本文实例讲述了Python实现的堆排序算法。分享给大家供大家参考,具体如下: 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的
2022-06-04

Python实现的基数排序算法原理与用法实例分析

本文实例讲述了Python实现的基数排序算法。分享给大家供大家参考,具体如下: 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,
2022-06-04

Python实现希尔排序算法的原理与用法实例分析

本文实例讲述了Python实现希尔排序算法的原理与用法。分享给大家供大家参考,具体如下: 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。 希尔排序的基本思想是:先将整个待排元素
2022-06-04

mysql数据备份与恢复实现方法分析

本文实例讲述了mysql数据备份与恢复实现方法。分享给大家供大家参考,具体如下: 本文内容:复制文件法利用mysqldump利用select into outfile其它(列举但不介绍)首发日期:2018-04-19有些时候,在备份之前要先
2022-05-14

Python实现的插入排序算法原理与用法实例分析

本文实例讲述了Python实现的插入排序算法原理与用法。分享给大家供大家参考,具体如下: 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)
2022-06-04

Python实现的选择排序算法原理与用法实例分析

本文实例讲述了Python实现的选择排序算法。分享给大家供大家参考,具体如下: 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直
2022-06-04

编程热搜

目录