B+树索引

  • 上一节中我们讨论的都是B+树的数据结构的由来以及他的一些操作,B+树索引在本质就是B+树在数据库中的一个实现,但是B+索引在数据库中有一个特点就是他的高扇出性,因此在数据库中,B+树的高度一般是2~3层,也就是对于查找某一个键值的行记录,最多只需要2 ~ 3次IO,我们假设一般的磁盘每秒可以做100次IO,那么2 ~3次就差不多0.02 秒 ~0.03秒

    • 扇入数(引入)就是引入了多少别的模块引到自己模块来,像光线汇聚。
    • 扇出(输出)就是自己模块被多少个其他模块拿来使用,像瀑布铺洒。
    • 用如下图解释
  • 数据库中的B+树索引分为聚集索引(clustered index)和辅助索引(secondary index),但是不管是聚集索引还是辅助索引,内部结构都是B+树,即高度平衡的,叶节点存放着所有的数据,聚集索引与非聚集索引不同的是,叶子节点存放的是否是一整行的信息

聚集索引

  • InnoDB存储引擎表是索引组织表,即表中数据依照主键顺序存放。而聚集索引就是按照每张表的主键构造一颗B+树,并且叶子节点存放整张表的行为记录数据,因此也让聚集索引的叶节点成为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。和B+树数据结构一样,每一个数据页都通过一个双向链表来进行连接

  • 由于实际的数据页只能按照一颗B+树进行排序,因此每张表只拥有一个聚集索引。在许多情况下,查询优化器非常倾向于采用聚集索引,因此,聚集索引能够让我们在索引的叶子节点上直接找到数据。此外,由于定义了数据的逻辑顺序,聚集索引能够特别快的访问针对范围的查询。查询优化器能够快速发现某一段范围的数据页需要进一步扫描筛选数据。

  • 我们用如下的表以及数据来说明,我们以认为的方式让每一个页只能存放两个行为记录:

create table t(a int not null primary key, b varchar(8000))insert into t select 1, repeat('a', 7000);insert into t select 2, repeat('a', 7000);insert into t select 3, repeat('a', 7000);insert into t select 4, repeat('a', 7000);
  • 我们如上表的定义,插入的数据使得目前每个页只能存放两个行记录,并且在构造的B+树上,数据页上存放的是完整的行记录,而在非数据页的索引页中,存放的仅仅是键值以及指向数据页的偏移量,而不是一个完整的行记录,因此我们构造这颗二叉树大致如下图:

  • 很多数据库文档中说过,聚集索引按照顺序物理的存储数据。如上图可以看到会有这种感觉。但是,如果聚集索引必须按照特定顺序存放物理记录的话,则维护成本会非常高。索引,聚集索引的存储并不是物理上连续的,相反,逻辑上才是连续的。有两点:

    • 一个是我们说过页面通过双向链表链接,页按照主键顺序排列
    • 每个页中的记录也是通过双向链表进行维护,物理存储上可以同样不按主键存储。
  • 聚集索引的一个好处是,他对于主键的排序查找和范围查找速度非常快。叶节点的数据就是我们要查询的数据,如果我们要查询一张注册用户的表,查询最后注册的10位用户,由于B+树索引是双向的,我们可以快速找到最后一个数据页,并去除10条记录,我们用explain分析如下:

EXPLAIN select * from moment order by id limit 10

  • 另一个是范围查找(range query),如果查找主键某个范围内的数据,通过叶节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可,如下:
EXPLAIN select * from moment where id > 1590 and id < 20000

  • 上图中的rows代表是一个预估值,,如果实际查询这条sql的数据条数发现更多17384条。

辅助索引

  • 对应辅助索引,也就是我们说的***非聚集索引***,叶节点不包含行的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签(bookmark),该书签用来告诉InnoDB存储引擎,哪里可以找到与索引对应的行数据。因为InooDB存储引擎表是索引组织表,因此,InnoDB存储引擎的辅助索引的书签就是相应数据的聚集索引的键值。如下图表示InnoDB存储引擎中辅助索引与聚集索引的关系。

  • 辅助索引的存在并不影响数据在聚集索引中的组织关系,因此每张表可以有多个辅助索引,当通过辅助索引来查找数据时候,InnoDB存储引擎会遍历辅助索引并通过叶子节点上的指针获得指向主键索引的主键,让后通过主键索引再来找一次最终找到一个完整的记录。

  • 案例

    • 如果在一颗高度为3(根算0 层)的辅助索引中查找数据,那么需要对这可辅助索引遍历3次找到指定主键
    • 如果聚集索引树的的高度同样是3,那么还需要对聚集索引在进行三次查找,才能最终找到一个完整的行数据所在的页(InnoDB最小存储单元是页)
    • 因此一共需要6次逻辑IO来访问最终的一个数据页。
  • 此处也行会有疑问,为啥不直接将负责索引叶子上的 书签指针之间指向行数据所在的页呢,这样就可以和聚集索引一样,通过遍历一个B+树的索引就可以找到我们需要的数据页所在的位置,少了一次IO操作。

    • 的确在某些情况,例如只读的时候,书签是行标识的方式的非聚集索引 比 书签是主键方式的非聚集索引要快。
    • 但是这是考虑在OLTP(Online Transaction Processing, 在线事务处理)应用的情况下,表可能还需要提供其他服务,例如,insert,update,delete等DML操作。当进行这种操作时候,书签为行的标识符方式的非聚集索引可能就需要不断的更新行标识符所指向的数据页面的位置,这时候的开销可能就大于书签为主键的非聚集索引了
  • 又有另外一个疑问,那么DML操作也会影响主键索引,这个效率也会降低吗:

    • DML操作的确会影响,但是主键是不能修改的,对于聚集索引来说 DML操作只会存在增加节点或者删除节点的情况,不会变更行的地址,而只是修改节点的指针数据而已
    • B+树的节点操作我们在之前章节 数据结构与算法–B树原理及实现 中有过详细的解释。

B+树索引的管理

  • 索引的创建和删除通过两种方法,一种ALTER TABLE,一种CREATE/DROP index,具体预发略
  • 索引可以索引整个列的数据,也可以索引一个列的开头N行数据,例如建立前100 行的索引如下:
alter TABLE t add key idx_b(b(100));
  • MySQL数据库存在一个普遍问题,所有对所有的添加,删除操作,MySQL数据库都是先创建一个新的临时表,然后把数据导入临时表,删除原表,在吧临时表重命名为原来的表,因此对于一张大表,添加,删除索引非长久时间,

  • InnoDB存储引擎从InnoDB Plugin开始,支持一种称为快速索引的创建方法,但是只限定于辅助索引,对于主键的创建和删除还是需要重建一张表。对于辅助索引的创建,InnoDB存储引擎会对表加上一个s锁。创建过程,不需要重建表,因此速度快,但是创建过程中上了S锁,因此创建过程中该表只进行读。

  • 删除的话更简单,只需要InnoDB存储引擎内部视图更新,将辅助索引空间标记可用即可,并删除MySQL内部视图上对改表索引定义。

  • 可用用如下方法查看索引:

show index from t

  • 上图中,有3个索引,一个主键索引,b列的非聚集索引,a,b的复合索引,如下图:

  • 具体每个列的含义:

    • Table:索引所在表名
    • Non_unique:非唯一索引,可以看到primaryKey是0,因为必须是唯一索引
    • Key_name:索引名称,我们可以通过这个名称来DROP INDEX
    • Sql_in_index:索引中该列的位置,如看到联合索引idx_a_b就比较直观的标识复合索引,位置有两个1,2
    • Column_name:索引列
    • Collation:列以什么方式存储在索引中。可以上‘A’或者NULL。B+树总是A,即排序的。如果使用了Heap存储引擎,并且建立了Heap索引,这里就会显示NULL了,因为Hash根据Hash桶来存放索引数据,而不是对数据进行排序
    • Cardinality:非常重要的值,表示索引中唯一值的数目的估计值。Cardinality表示的行数如果非常小,说明我们可能不需要这个索引,比如以上案例,只有四条数据,完全没有必要索引的。
    • Sub_part:是否是列的部分被索引。如果看idx_b这个索引,这里显示100,表示我们只索引b列的前100个字符,如果索引整个列,该字段值是NULL
    • Packed:关键字如何被压缩。如果没有被压缩,则为NULL
    • Null:是否索引的列含义NULL值,可以看到idx_b这里是yes,因为我们定义b列的时候允许NULL
    • Index_type:索引类型。InnoDB存储引擎只支持B+树索引,所以这里显示的都是BTREE
    • Comment:注释
  • 其中Cardinality值比较关键,查询优化器 会根据这个值来判断是否使用这个索引。但是这个值并不是实时更新,并非每次索引的更新都会更新改值,这样代价太大。因此这个值是不太准确的,只是一个估计值。上面显示的Cardinality为2,但是显然表中有四条数据,这个应该是4的。如果需要更新Cardinality信息,可以使用命令如下:

ANALYZE table t
  • 不过这条命令在每个系统上可能得到的结果不一样,因为AnalyzeTable 现在还存在问题,可能会影响得到最后的结果,另一个问题是MySql对Cardinality计数的问题
  • 某些情况下可能会发生即使你建立了索引,但是查询这个字段确没有用到,或者,explain两条基本一样的语句,但是最终出来的结果一个用索引,一个不用索引,这个都和查询优化器对Cardinality的数量判断做的优化有关系。

上一篇:数据结构与索引-- mysql InnoDB存储引擎索引
下一篇:数据结构与索引-- mySql索引诡异事件

数据结构与索引-- B+树索引相关推荐

  1. b树索引 java_B树索引最通俗易懂的介绍

    先来一段有莫的对话: 前几天下班回到家后正在处理一个白天没解决的bug,厕所突然传来对象的声音: 对象:xx,你有<时间简史>吗? 我:我去!妹子,你这啥癖好啊,我有时间也不会去捡屎啊! ...

  2. MySQL 索引 :哈希索引、B+树索引、最左前缀匹配规则、全文索引

    文章目录 索引 什么是索引 索引优缺点与适用场景 常见的索引 哈希索引 自适应哈希索引 B+树索引 聚集索引 非聚集索引 使用方法 联合索引 最左前缀匹配规则 覆盖索引 全文索引 使用方法 索引 什么 ...

  3. MySQL 索引 :哈希索引、B+树索引、全文索引

    文章目录 索引 引言 常见的索引 哈希索引 自适应哈希索引 B+树索引 聚集索引 非聚集索引 使用方法 联合索引 最左前缀匹配规则 覆盖索引 全文索引 使用方法 索引 引言 为什么需要索引? 倘若不使 ...

  4. MySQL~B+树索引(聚簇、非聚簇)和一些B+树索引的注意点

    文章标题 聚簇索引 非聚簇索引 联合索引 B+树索引的注意点 索引按照物理实现方式,索引可以分为2种: 聚簇索引和 非聚簇索引 非聚簇索引又被称为二级索引或者辅助索引 也可以称为聚集索引.非聚集索引 ...

  5. MySQL B+树索引和哈希索引介绍

    * GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 索引介绍 索引是一种特殊的数据库结构,被设计用来快速查询数据库表中的特定记录.索引有多种类型,就像字典有拼音查找和偏旁 ...

  6. MySQL-Btree索引和Hash索引初探

    文章目录 生猛干货 官方文档 MySQL支持的索引类型 B树索引 B树索引的特点 什么情况下会使用到B树索引 Btree索引的使用限制 hash索引 hash索引的特点 hash索引的限制 为啥要使用 ...

  7. mysql索引 聚集索引_MySql数据库索引-聚集索引和辅助索引

    InnoDB存储引擎索引: B+树索引:不能找到一个给定键值的具体行,能找到的只是被查找数据行所在的页.然后把页加载到内存,在查询所要的数据. 全文索引: 哈希索引:InnoDB会根据表的使用情况自动 ...

  8. 覆盖索引与联合索引_浅析MySQL的索引覆盖和索引下推

    写在前面 在MySQL数据库中,索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点,索引就是为了提高数据查询的效率.今天我们来聊聊在MySQL索引优化中两种常见的方式,索引覆盖和 ...

  9. mysql数据索引失效_MySQL索引失效的几种情况

    1.索引无法存储null值 a.单列索引无法储null值,复合索引无法储全为null的值. b.查询时,采用is null条件时,不能利用到索引,只能全表扫描. 为什么索引列无法存储Null值? a. ...

最新文章

  1. android shortcut livefoulder
  2. 056_Object对象方法
  3. nacos单机模式使用mysql库_Nacos docker 单机模式,mysql 搭建
  4. Git 忽略已经提交的文件
  5. 03-谷歌浏览器安装Sence
  6. 使用springboot遇到的的异常
  7. 多标签文本分类研究进展
  8. 面向对象三大特性之——封装
  9. 阿里巴巴图标库字体iconfont旋转
  10. RT-Thread邮箱
  11. Qt中出现 exited with code 3错误的其中之一原因
  12. 2021齐齐哈尔实验中学高考成绩查询,齐齐哈尔名列前茅的4所高中,成绩一目了然,谁是市内最强中学?...
  13. HTML链接标志,html-4 超级链接标志使用.doc
  14. 51单片机教程:51单片机驱动四个8*8点阵,拼凑16*16点阵显示标准汉字。
  15. 软件测试适合女孩子吗?从以下几点告诉你答案
  16. vue+typescript(vben-admin)前端开发
  17. 人人开源前后端分离部署到阿里云服务器
  18. 为网站配置免费的HTTPS证书 3-4
  19. 带你解析微信公众号灵魂有香气的女子的创始人李筱懿
  20. 服务器放在机柜_服务器机柜摆放有哪几种方式?

热门文章

  1. IOS之学习笔记十四(协议的定义和实现)
  2. 求数组里面的最大值和最小值
  3. 表头合并_多个Excel表格合并数据麻烦?试试Power Query轻松帮你解决
  4. js监听地址栏变化_vue中本地储存也可以实时监听
  5. 年月跨度_建筑结构丨国内跨度最大的张弦桁架工程——合肥滨湖国际会展中心二期首榀桁架滑移成功...
  6. 竟然有如何奇葩的如厕方式......
  7. 阿里云开源的Blink,计算能力很疯狂:一眨眼,全部都算好!
  8. a*算法的时间复杂度_数据结构(1)——算法和时间复杂度
  9. 打印机一直显示正在打印中_中国和桌面3D打印机正在引领3D打印市场
  10. 10以内的分解与组成怎么教_狗狗酷炫的飞盘游戏怎么玩?分解步骤教你快速学会...