一、定义

索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。
本质:索引是数据结构。

二、B-Tree

m阶B-Tree满足以下条件:

  1. 每个节点至多可以拥有m棵子树。
  2. 根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶,也是树)。
  3. 非根非叶的节点至少有的Ceil(m/2)个子树(Ceil表示向上取整,如5阶B树,每个节点至少有3个子树,也就是至少有3个叉)。
  4. 非叶节点中的信息包括[n,A0,K1,A1,K2,A2,…,Kn,An],,其中n表示该节点中保存的关键字个数,K为关键字且Ki<Ki+1,A为指向子树根节点的指针。
  5. 从根到叶子的每一条路径都有相同的长度(叶子节点在相同的层)

B-Tree特性:

  1. 关键字集合分布在整颗树中;
  2. 任何一个关键字出现且只出现在一个节点中;
  3. 每个节点存储date和key;
  4. 搜索有可能在非叶子节点结束;
  5. 一个节点中的key从左到右非递减排列;
  6. 所有叶节点具有相同的深度,等于树高h。

三、B+Tree

B+Tree与B-Tree的差异在于:

  1. B+Tree非叶子节点不存储data,只存储key;
  2. 所有的关键字全部存储在叶子节点上;
  3. 每个叶子节点含有一个指向相邻叶子节点的指针,带顺序访问指针的B+树提高了区间查找能力;
  4. 非叶子节点可以看成索引部分,节点中仅含有其子树(根节点)中的最大(或最小)关键字;

四、B/B+树索引的性能分析

依据:使用磁盘I/O次数评价索引结构的优劣

主存和磁盘以页为单位交换数据,将一个节点的大小设为等于一个页,因此每个节点只需一次I/O就可以完全载入。

根据B树的定义,可知检索一次最多需要访问h个节点
渐进复杂度:O(h)=O(logdN)
dmax=floor(pagesize/(keysize+datasize+pointsize))

一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3,3层可存大约一百万数据)

B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存)

B+Tree内节点不含data域,因此出度d更大,则h更小,I/O次数少,效率更高,故B+Tree更适合外存索引。

五、MySQL索引实现

1. MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址;MyISAM主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复;

2. InnoDB的数据文件本身就是索引文件,叶节点包含了完整的数据记录,这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键。

InnoDB的辅助索引data域存储相应记录主键的值而不是地址;

辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录;

3.页分裂问题

如果主键是单调递增的,每条新记录会顺序插入到页,当页被插满后,继续插入到新的页;

如果写入是乱序的,InnoDB不得不频繁地做页分裂操作,以便为新的行分配空间。页分裂会导致移动大量数据,一次插入最少需要修改三个页而不是一个页。

如果频繁的页分裂,页会变得稀疏并被不规则地填充,所以最终数据会有碎片。

六、总结

了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助

  1. 为什么不建议使用过长的字段作为主键?
  2. 为什么选择自增字段作为主键?
  3. 为什么常更新是字段不建议建立索引?
  4. 为什么选择区分度高的列作为索引?区分度的公式是count(distinct col)/count(*)
  5. 尽可能的使用覆盖索引

MySQL索引底层实现的更多相关文章

  1. MySQL索引底层数据结构

    一.何为索引? 1.索引是帮助数据库高效获取数据的排好序的数据结构. 2.索引存储在文件中. 3.索引建多了会影响增删改效率. (下面这张图为计算机组成原理内容,每查询一次索引节点,都会进行一次磁盘I ...

  2. 深入理解MySQL索引底层数据结构

    作者:IT王小二 博客:https://itwxe.com MySQL 索引相关的数据结构有两种,一种是 B+tree,一种是 Hash,那么为什么在 99.99% 的情况下都使用的是 B+tree索 ...

  3. 一文搞懂mysql索引底层逻辑,干货满满!

    一.什么是索引 在mysql中,索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录.通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列即可 ...

  4. MySQL索引底层实现原理

    优秀博文: MySQL索引背后的数据结构及算法原理 B树.B-树.B+树.B*树[转],mysql索引 MySQL 和 B 树的那些事 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮 ...

  5. 007 --MySQL索引底层实现原理

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

  6. 深入理解Mysql索引底层数据结构与算法

    索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构对比 二叉树 左边子节点的数据小于父节点数据,右边子节点的数据大于父节点数据. 如果col2是索引,查找索引为89的行元素,那么只需要查 ...

  7. mysql索引底层的数据结构和算法

    1.       为什么要用索引 索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构.索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要. 索 ...

  8. Mysql索引底层数据结构与算法

    索引是什么 索引是帮助MySQL高效获取数据的排好序的数据结构. 索引存储在文件里 补充知识: 磁盘存取原理: * 寻道时间(速度慢,费时) * 旋转时间(速度较快) 磁盘IO读取效率: * 单次IO ...

  9. 深入理解 MySQL 索引底层原理

    https://mp.weixin.qq.com/s/qHJiTjpvDikFcdl9SRL97Q

随机推荐

  1. Unity系统自带函数生命周期以及相互关系

    官方参考手册:http://docs.unity3d.com/Manual/ExecutionOrder.html unity脚本从唤醒到销毁都有着一套比较完善的生命周期,添加任何脚本都要遵守生命周期 ...

  2. (2.4)备份与还原--WAL与备份原理

    预写式日志(Write-Ahead Logging (WAL))  部分转自:http://www.cnblogs.com/wenBlog/p/4423497.html SQL Server中使用了W ...

  3. JavaScript工具库 lodash 中文文档 英文文档

    https://lodash.com/docs/    英文版 http://lodashjs.com/docs/   中文版 http://www.css88.com/doc/lodash/ 中文版 ...

  4. 汇编文件后缀.s与.S

    转载:http://www.cnblogs.com/IamEasy_Man/archive/2011/08/10/2134212.html 一.大小写后缀的区别: .s:  汇编语言源程序;汇编 .S ...

  5. HMM、MEMM、CRF模型比较和标注偏置问题(Label Bias Problem)

    本文转自:http://www.cnblogs.com/syx-1987/p/4077325.html 路径1-1-1-1的概率:0.4*0.45*0.5=0.09 路径2-2-2-2的概率:0.01 ...

  6. 漫谈DOM 事件流的三个阶段

    一丶 流 什么是流? 比如 react 中的单项数据流,Node.js 中的流,或者本文中的 DOM 事件流,都是流的具体体现.专业地讲,流是程序输入或输出的一个连续的字节序列:通俗地讲,流是有方向的 ...

  7. python16_day22【cmdb注释】

    https://github.com/willianflasky/growup/tree/master/s16/day23/learnMadKing

  8. opencart 单入口文件简单分析

    opencart 单入口文件简单分析   opencart是基于mvcl的商城系统,据说是一个外国有人单独开发.比较牛叉.但是又不大符合国人习惯,目前国内opencart社区也是不少. 简单分析了下单 ...

  9. HDU 1116 Play on Words(欧拉路径(回路))

    http://acm.hdu.edu.cn/showproblem.php?pid=1116 题意:判断n个单词是否可以相连成一条链或一个环,两个单词可以相连的条件是 前一个单词的最后一个字母和后一个 ...

  10. ruby 时间 今天 昨天

    today = Time.now.strftime('%Y-%m-%d') yesterday = (Time.now - 1.day).strftime('%Y-%m-%d')