文章目录

  • 一、索引概述
    • 1.索引的定义
    • 2.索引的作用
    • 3.索引的优缺点
  • 二、索引结构
    • 1.概述
    • 2.索引的演进
      • 1.二叉树
      • 2.B-Tree
      • 3.B+Tree
      • 4.Hash
  • 二、索引分类
    • 1.MySQL中索引分类
    • 2.MySQL存储引擎中索引分类

一、索引概述

1.索引的定义

索引(index)是一种数据结构,使用这种数据结果可以高效的检索数据。一般来说,索引是有序的。在MySQL中,除数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

2.索引的作用


如上表,假如我们要执行的SQL语句为 : select * from user where age = 45;

  • 无索引情况。需要从第一行开始扫描,一直扫描到最后一行,这样进行全表扫描,效率低下。
  • 有索引情况。
    如果我们针对于这张表建立了索引,假设索引结构就是二叉树,那么也就意味着,会对age这个字段建立一个二叉树的索引结构。此时我们在进行查询时,只需要扫描三次就可以找到数据了,极大的提高的查询的效率。

备注: 这里我们只是假设索引的结构是二叉树,介绍一下索引的大概原理,只是一个示意图,并不是索引的真实结构,索引的真实结构,后面会详细介绍。

3.索引的优缺点

优点

  • 提高数据检索的效率,降低数据库的IO成本
  • 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。

缺点

  • 索引列也是要占用空间的。
  • 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低。

二、索引结构

1.概述

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种:

上述是MySQL中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持情况。

注意: 我们平常所说的索引,如果没有特别指明,都是指B+树结构组织的索引。

2.索引的演进

1.二叉树

二叉树是一种相对简单的数据结构,这里从二叉树开始介绍,分析其中有优缺点,以及最后MySQL为什么会选择B+Tree。
如下是比较理想的二叉树:

如果需要检索20,则只需要进行4次检索和比较。
但如果是主键自增顺序插入,则二叉树会退化为一个链表,如下图:

此时需要检索20,就需要6次的检索和比较。
所以,如果选择二叉树作为索引结构,会有一下缺点:

  • 顺序插入时,会形成一个链表,查询性能大大降低。
  • 大数据量情况下,层级较深,检索速度慢。

这里有的同学可能会想到使用红黑树,红黑树是一颗自平衡二叉树,那这样即使是顺序插入数据,最终形成的数据结构也是一颗平衡的二叉树,结构如下:

相比二叉树,红黑树解决了顺序插入时会退化成链表的问题,但还是存在一个缺点:

  • 大数据量情况下,层级较深,检索速度慢。

所以,在MySQL的索引结构中,并没有选择二叉树或者红黑树,而选择的是B+Tree,那么什么是B+Tree呢?在详解B+Tree之前,先来介绍一个B-Tree。

注意:没有所谓B减树,B减数实际就是B树,只是表示时都使用了B-Tree,我个人都统计B树或B杠数。

2.B-Tree

B-Tree,B树是一种多叉路衡查找树,相对于二叉树,B树每个节点可以有多个分支。以一颗最大度数(max-degree)为5(5阶)的b-tree为例,那这个B树每个节点最多存储4个key,5个指针:

备注:树的度数指的是一个节点的子节点个数。

这是一个数据结构可视化网站:http://www.rmboot.com/Algorithms.html
我们选择B-Tree来演示。http://www.rmboot.com/BTree.html

插入一组数据: 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250 。然后观察一些数据插入过程中,节点的变化情况。

特点:

  • 5阶的B树,每一个节点最多存储4个key,对应5个指针。
  • 一旦节点存储的key数量到达5,就会裂变,中间元素向上分裂。
  • 在B树中,非叶子节点和叶子节点都会存放数据。

我们再看看B+Tree,为什么MySQL选择了B+Tree。

3.B+Tree

B+Tree是B-Tree的变种,我们以一颗最大度数(max-degree)为4(4阶)的b+tree为例,其结构示意图:

我们可以看到,两部分:

  • 绿色框框起来的部分,是索引部分,仅仅起到索引数据的作用,不存储数据。
  • 红色框框起来的部分,是数据存储部分,在其叶子节点中要存储具体的数据。

我们选择B+Tree来演示。http://www.rmboot.com/BPlusTree.html

插入一组数据: 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250 。然后观察一些数据插入过程中,节点的变化情况。

最终我们看到,B+Tree 与 B-Tree相比,主要有以下三点区别:

  • 所有的数据都会出现在叶子节点。
  • 叶子节点形成一个单向链表。
  • 非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。

上述为标准的B+Tree结构,MySQL对原标准的B+Tree做了进一步优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能,利于排序。

B+Tree和B-Tree的不同点:

  • B-Tree的叶子节点没有指针,B+Tree树有。所以B+Tree在做范围查询时更具有优势,从索引中找到开始的元素,然后顺着指针遍历。而B-Tree则需要在索引数中多差查找。
  • B-Tree的非叶子节点也存放数据,B+Tree树则不会存放。这使得每一个磁盘页能存储更多的元素,从而能让树更矮,减少IO次数,提高效率。
  • B+Tree查询时必须查询到叶子节点,B-Tree则不需要。所以B+Tree的会更加稳定。
4.Hash

MySQL中除了支持B+Tree索引,还支持一种索引类型—Hash索引。
1.结构
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。

如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称为hash碰撞),可以通过链表来解决。

2.特点

  • Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,< ,…)
  • 无法利用索引完成排序操作
  • 查询效率高,通常(不存在hash冲突的情况)只需要一次检索就可以了,效率通常要高于B+tree索引

3.存储引擎支持
在MySQL中,支持hash索引的是Memory存储引擎。 而InnoDB中具有自适应hash功能,hash索引是InnoDB存储引擎根据B+Tree索引在指定条件下自动构建的。

思考题: 为什么InnoDB存储引擎选择使用B+tree索引结构?
A. 相对于二叉树,层级更少,搜索效率高;
B. 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
C. 相对Hash索引,B+tree支持范围匹配及排序操作;

二、索引分类

1.MySQL中索引分类

在MySQL数据库,将索引的具体类型主要分为以下几类:主键索引、唯一索引、常规索引、全文索引。

2.MySQL存储引擎中索引分类

在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

聚集索引和二级索引的具体结构如下:

  • 聚集索引的叶子节点下挂的是这一行的数据 。
  • 二级索引的叶子节点下挂的是该字段值对应的主键值。

当我们执行如下的SQL语句时,具体的查找过程是什么样子的。

具体过程如下:

  1. 由于是根据name字段进行查询,所以先根据name='Arm’到name字段的二级索引中进行匹配查找。但是在二级索引中只能查找到 Arm 对应的主键值 10。
  2. 由于查询返回的数据是*,所以此时,还需要根据主键值10,到聚集索引中查找10对应的记录,最终找到10对应的行row。
  3. 最终拿到这一行的数据,直接返回即可。

回表查询: 这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。

学习了MySQL的索引,我们可以应该能回答一下两个问题:

  1. 以下两条SQL语句,那个执行效率高? 为什么?
    A. select * from user where id = 10 ;
    B. select * from user where name = ‘Arm’ ;
    备注: id为主键,name字段创建的有索引;
    答案:A 语句的执行性能要高于B 语句。因为A语句直接走聚集索引,直接返回数据。 而B语句需要先查询name字段的二级索引,然后再查询聚集索引,也就是需要进行回表查询。

  2. InnoDB主键索引的B+tree高度为多高呢?
    假设:一行数据大小为1k,一页中可以存储16行这样的数据。InnoDB的指针占用6个字节的空间,主键即使为bigint,占用字节数为8。
    如果高度为2:
    n * 8 + (n + 1) * 6 = 16*1024 , 算出n约为 1170
    1171 * 16 = 18736
    也就是说,如果树的高度为2,则可以存储 18000 多条记录。
    如果高度为3:
    1171 * 1171 * 16 = 21939856
    也就是说,如果树的高度为3,则可以存储 2200w 左右的记录。
    所以,一般表数据上了2000w就要进行分表了。

【MySQL 面试系列】索引原理相关推荐

  1. MySQL索引的理解学习,面试不问索引原理就是事务原理

    目录 MySQL执行SQL的整体流程 引言, MySQL索引底层学习原因 磁盘介绍(理解磁盘IO) 索引底层数据结构B+树 B+树(聚集索引) B+树(辅助索引) 思考一下为何使用B+树结构, 不是B ...

  2. 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  3. mysql b tree索引原理_B+Tree原理及mysql的索引分析

    一.索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之 ...

  4. java mysql 全文索引_MySQL索引原理

    什么是索引? "索引"是为了能够更快地查询数据.比如一本书的目录,就是这本书的内容的索引,读者可以通过在目录中快速查找自己想要的内容,然后根据页码去找到具体的章节. 数据库也是一样 ...

  5. 全局索引 前缀索引_面试系列 索引种类与优化

    索引虽然快,但是占用了额外的空间,所以需要有一定权衡 覆盖索引 回表查询 InnoDB的普通索引无法直接定位行记录,所以普通索引的查询过程是怎么样的呢? 通常情况下,需要扫码两遍索引树.这就是所谓的回 ...

  6. mysql gis index 索引原理_Mysql 索引原理及优化

    Mysql 索引原理及优化 什么是索引 为什么需要索引? 索引是数据表种一个或者多个列进行排序的数据结构 索引能够大幅提升检索速度 创建.更新索引本身也会耗费空间和时间 查找结构进化史 线性查找:一个 ...

  7. 【MySQL】数据库索引原理 | 索引数据结构 | B+Tree

    数据库索引原理 | 索引数据结构 | B+Tree 文章目录 数据库索引原理 | 索引数据结构 | B+Tree 一. 数据库索引简介 二. 红黑树 与 B-Tree 1. 红黑树 2. B-Tree ...

  8. mysql的覆盖索引原理_「Mysql索引原理(七)」覆盖索引

    通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分.索引确实是一种查找数据的高效方式,但是MySQL也可 ...

  9. mysql gis index 索引原理_从原理到优化,深入浅出数据库索引

    MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 数据库查询是数据库的最主要功能之一,我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的 ...

  10. Mysql数据库的索引原理

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

最新文章

  1. 微信公众平台开发(38)一站到底在线答题
  2. matlab高中必修三数学模拟,基于MATLAB的模拟调制实验报告
  3. windows设置自动清理log
  4. IOS之使用纯代码push ViewController
  5. 感性理解Berlekamp-Massey算法
  6. Linux debian ubuntu的PyCharm无法正常输入中文
  7. qt为lineedit添加背景图片代码_Qt中事件的理解(2)
  8. SVO深度解析(三)之深度滤波(建图部分)
  9. Python参考手册
  10. echarts动态显示某个省或某个市
  11. linux文件夹压缩与分卷压缩
  12. 2022“美亚杯”第八届中国电子数据取证大赛-个人赛题目
  13. meteor使用简介
  14. Mstar的Monitor方案OSD 菜单制作(五)——icon绘制
  15. 问题 J: 机器人足球
  16. Vibrant Ink Theme for IntelliJ IDEA
  17. Smart movie Java_智能影院下载-smartmovie智能影院【手机端+PC端+教程+工具】-东坡下载...
  18. CAJ与PDF与WORD转化方法
  19. 郭敬明最经典的45句话
  20. P5108 仰望半月的夜空 SAM+线段树覆盖

热门文章

  1. Android Remote Service
  2. Chtholly Nota Seniorious
  3. SSL证书会不会过期?域名SSL证书过期了怎么办?
  4. aria2 32bit Android,【各版本整合】32/64位Aria2 Tools - 支持RPC协议 AriaNG(客户端+网页版)...
  5. c语言中j%2什么意思,C语言中if(j%2) continue;
  6. 不重装系统解决win10更新错误0x800f0922
  7. I2C协议---I2C时序图解析
  8. Codeforces Round #554 (Div. 2) A. Neko Finds Grapes
  9. 怎么开发联机小游戏_微信小游戏创意大赛火热进行中,小游戏联机对战引擎免费用...
  10. ABeam Insight | 女性科技系列(1):女性科技(FemTech)简述