InnoDB 索引原理
InnoDB索引原理
索引能够提高访问的速率
B+树索引(最为常用和最为有效)、全文索引、哈希索引。
数据库中的B+树索引可以分为聚集索引和辅助索引,但是不管是聚集还是辅助的索引,其内部都是B+树,是高度平衡的,叶子结点存放着所有的数据。聚集索引和辅助索引最大对的不同就是,叶子结点存放的是否是一整行的信息。
B+树
B+树是为磁盘或者其它直接存取辅助设备设计的一种平衡树,在B+树中,所有纪录结点都是按照键值的大小顺序存放在同一层的叶子结点上,由各叶子结点指针进行连接。
举个例子,上面为index page、下面为leaf page,如下图:

插入
插入分为三种情况,但都必须保证插入后叶子结点中的纪录依然排序。

还是根据上面的那副图作为例子,往里面加入28,我们索引到具体的位置,在25-30中间,我们发现当前的情况为叶子结点不为空,父亲结点也不为空,查询表格发现我们可以直接将纪录插入到叶子结点中,所以如下:

接着往里面插入70,我们发现在叶子结点已经满了,但是父亲结点并没有满,所以需要将叶子结点进行分裂,因为70在最右边,所以将中间的数字60向上移动,放到原来父亲结点中75的位置,而75则向后移动一位,得到如下图:

注意:因为图片大小关系,图中的叶子结点中的双链表没有显示,但是实际是应该显示的。
最后插入95,根据图片索引到其插入位置为叶子结点中90的后面,此时我们发现叶子结点和父亲结点都已经满了,于是它们两个都需要进行分裂,首先将叶子结点中的中间位置85向上移动,并且同时分裂成两个叶子结点(左边比85小,右边比85大),此时父亲结点也放不下85,于是将中间位置的60向上移动单独成为一个结点,左子结点中的值比60小,右子结点的值比60大,具体如下图:

旋转
上面的操作为了保持平衡而进行大量的拆分页操作,因为B+树主要用于磁盘,而拆分则意味着磁盘的操作,所以要在尽可能的情况下减少拆分的动作。B+树也提供了旋转的功能:在当前叶子结点满了,但是兄弟结点没有满的情况下,可以将部分结点移动到兄弟结点中,并且调整父亲结点。
比如在前面提到的加入70,其图可以为:

可以看到,采用旋转操作使得B+树减少了一次页的拆分动作,而且还保持了高度为2。
删除
B+树使用填充因子来控制树的删除变化,填充因子最小可设为50%,同样的,B+树的删除操作需要保证删除后叶子结点中的纪录依然排序,删除分为好几种情况,如下:

我们就继续在插入的树的基础上进行删除操作。删除70后,发现叶子结点和其父亲结点的值的个数并没有小于一半,所以不需要进行其它的操作。

接下来删除25,因为同样是删除表格中的第一种操作,所以直接删除即可,但是需要注意的是,其父亲结点仍然存在25,所以需要将最左边的28更新到父亲结点中即可,如图下:

接着删除60,我们发现删除60后,该叶子结点已经小于填充因子,因此这种情况属于表格中的第三种情况,则需要合并兄弟结点,因为剩余的数字小于75,所以要合并左边的兄弟结点,同时把根结点的60删除掉,合并它的两个子结点,如图下:

索引
数据库中的B+树索引可以分为聚集索引和辅助索引,但是不管是聚集索引还是辅助索引,其内部都是B+树的,即高度平衡的,叶子结点存放着所有的数据,它们不得不同点在于,叶子结点存放的是否是一整行信息。
聚集索引
InnoDB存储引擎表是索引组织表,即表中数据按照主键顺序存放,而聚集索引就是按照每张表的主键构造一颗B+树,同时叶子结点存放的即为整张表的行纪录数据(聚集索引的叶子结点也称为数据页)。聚集索引的这个特性也决定了索引组织表中数据也是索引的一部分,和B+树数据结构一样,每个数据页都通过一个双向链表来进行链接。
聚集索引的另外一个好处是,它对于主键的排序查找和范围查找速度非常快。叶子结点的数据就是用户所要查询的数据。另外一个是范围查询,即如果要查找住主键某一个范围内的数据,通过叶子结点的上层中间结点就可以得到页的范围,之后直接读取数据页即可。
辅助索引
辅助索引,叶子结点并不包含行纪录的的全部数据,叶子结点除了包含键值以外,每个叶子结点中的索引行还包含了一个书签,该书签用来告诉InnoDB存储引擎哪里可以找到索引相对应的行数据,因为InnoDB存储引擎表是索引组织表,因此辅助索引的书签就是相应行数据的聚集索引键。也就是说当通过辅助索引查找数据时,InnoDB会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键。然后再通过主键索引找到一行完整的数据。
建索引的几大规则
- 最左前缀匹配原则,数据库会一直向右匹配直到遇到范围查询就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的;
- =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序;
- 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,所以最好别对这些字段创建索引;
- 索引列不能参与计算,保持列“干净”,因为B+树中存的都是数据表中的字段值,但进行检索的时候,需要把所有元素都应用函数才能比较,显然成本太大;
- 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可;
索引优化
应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描;
例子:select id from t where num is null
应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描;
应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描;(可以使用union来代替or)
in 和 not in 也要慎用,因为in会使系统无法使用索引,而只能直接搜索表中的数据,对于连续的数值,能用 between 就不要用 in;
尽量避免在索引过的字符数据中,使用非打头字母搜索,这也使得引擎无法利用索引;
比如:SELECT * FROM T1 WHERE NAME LIKE ‘%L%’
应尽量避免在 where 子句中对字段进行表达式操作或者函数操作,都会导致引擎放弃使用索引而进行全表扫描;
比如:SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’
应用
联合索引
联合索引是指对表上的多个列进行索引,加快搜索的效率。
覆盖索引
从辅助索引中就可以得到查询的纪录,避免了去查询聚集索引中的纪录所造成的消耗。
InnoDB 索引原理的更多相关文章
- 0614MySQL的InnoDB索引原理详解
转自http://www.cnblogs.com/shijingxiang/articles/4743324.html MySQL的InnoDB索引原理详解 http://www.admin10000 ...
- MySQL系列(九)--InnoDB索引原理
InnoDB在MySQL5.6版本后作为默认存储引擎,也是我们大部分场景要使用的,而InnoDB索引通过B+树实现,叫做B-tree索引.我们默认创建的 索引就是B-tree索引,所以理解B-tree ...
- MySQL的InnoDB索引原理详解
摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇 ...
- MySQL的InnoDB索引原理详解 (转)
摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...
- 深入浅出分析MySQL MyISAM与INNODB索引原理、优缺点、主程面试常问问题详解
本文浅显的分析了MySQL索引的原理及针对主程面试的一些问题,对各种资料进行了分析总结,分享给大家,希望祝大家早上走上属于自己的"成金之路". 学习知识最好的方式是带着问题去研究所 ...
- MySQL InnoDB 索引原理
本文由 网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...
- 深入浅出分析MySQL MyISAM与INNODB索引原理、优缺点分析
本文浅显的分析了MySQL索引的原理及针对主程面试的一些问题,对各种资料进行了分析总结,分享给大家,希望祝大家早上走上属于自己的"成金之路". 学习知识最好的方式是带着问题去研究所 ...
- mySql---剖析InnoDB索引原理
摘要: 本篇为参考别人的文章(http://blog.csdn.net/voidccc/article/details/40077329) 1 各种树形结构 本来不打算从二叉搜索树开始,因为网上已经有 ...
- mysql innodb索引原理
聚集索引(clustered index) innodb存储引擎表是索引组织表,表中数据按照主键顺序存放.其聚集索引就是按照每张表的主键顺序构造一颗B+树,其叶子结点中存放的就是整张表的行记录数据,这 ...
随机推荐
- 【JavaScript学习】-JS内置对象3-String对象
定义: 定义字符串的方法就是直接赋值,例如:var mystr="Javascript is good!"; 访问字符串的属性: length属性 eg:var myl=mystr ...
- echarts3 清空上一次加载的series数据
今天做图表的时候发现了一个问题,想和大家分享一下 我有一个下拉选框,每次选中都切换不同的数据,数据是从后台查询获取的,但是如果后台返回了数据每次渲染都没有问题,如果后台没有返回数据,但是我在渲染图表的 ...
- abelkhan服务器框架
abelkhan是一个开源的游戏服务器框架.目标是提供一个稳定.高效.可扩展的服务器框架. github:https://github.com/qianqians/abelkhan 论坛:http:/ ...
- I/O多路复用之epoll实战
概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程 通俗理解(摘自网上一大神) 这些名词比较绕口,理解涵义就好.一个epoll场景:一个酒吧服务员(一个线程),前 ...
- 在SOUI中使用网格布局
在实现网格布局前,SOUI支持两种布局形式:相对布局,和线性布局,其中线性布局是2017年2月份才支持的布局. 这两年工作都在Android这里,Android里有号称5大布局(RelativeLay ...
- python编程快速上手之第6章实践项目参考答案
#!/usr/bin/env python3.5 2 #coding:utf-8 3 # 4 # 这个项目主要目的是字符串的处理,简单格式化输出 5 tableData = [['apples','o ...
- 【SqlServer系列】表连接
1 概述 1.1 已发布[SqlServer系列]文章 [SqlServer系列]MYSQL安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 1.2 本篇 ...
- [POJ2104/HDU2665]Kth Number-主席树-可持久化线段树
Problem Kth Number Solution 裸的主席树,模板题.但是求k大的时候需要非常注意,很多容易写错的地方.卡了好久.写到最后还给我来个卡空间. 具体做法参见主席树论文<可持久 ...
- kali切换字符界面模式和切换图形界面模式
我也是走了很多弯路,下面把正确的命令写出来,网上的不是说不正确,是linux命令做出了更改 Systemd是一种新的linux系统服务管理器 它替代了init, 直接上命令吧! 切换至字符界面 sud ...
- js中变量的连续赋值
今天遇到了一个连续赋值的经典案例,网友们给出的答案也是五花八门,看起来有些繁琐,我也来说说自己的看法. 下面就是这个经典案例: var a = {n: 1}: var b = a; a.x = a = ...