如何理解Mysql的索引及他们的原理--------二叉查找树和平衡二叉树和B树和B+树

1.索引是什么东西?

索引就是一个数据结构,我们把表中的记录用一个适合高效查找的数据结构来表示,目的就是让查询变得更高效。

2.它到底怎么运作的?

这个问题就说来话长了,且听我慢慢道来:

在mysql中使用最广泛的数据引擎是InnoDB 引擎,它里面用的是 B+ 树索引。

我们重点分析一下这个索引的原理:

要想理解B+树索引要先从 二叉查找树,平衡二叉树和 B 树说起因为B+树索引就是由他们演化而来:

什么是二叉查找树?

 

满足这样条件的就叫二叉查找树:

每个节点左边节点的值都小于该节点,右边节点的值都大于该节点,没有值相等的节点,最顶端的节点也就是“45”被称为根节点。

二叉查找树的查找过程:

若根结点的值等于查找的值,成功,

否则,若小于根结点的值,递归查左子树(也就是根节点左边的所有节点形成的树)

若大于根结点的值,递归查右子树(也就是根节点右边所有节点形成的树)。

假设用二叉查找树创建book表的索引:

 

索引如下:

图一

 

此处的bid为主键,每个节点存储了主键的值和该条记录的内容。

如果我要查找bid为6的图书的信息,则先用6和根节点的主键值7比较发现比7小,

然后6再和7左边的节点5比较发现比5大找到5右边的节点6,找到了,取出6对应的记录行的值ee.

总共经历了3次比较,如果扫描全表需要经过5次比较。

 

什么是平衡二叉树?

如果索引是这样:

图二

 

想要找到主键键值为9的记录就需要6次比较,索引的优势完全体现不出来。

为什么会这样?原因就在于这棵树太高了,如果能想办法把它变得矮一点,胖一点就完美了。于是平衡二叉树闪亮登场:

平衡二叉树首先也是一个二叉树,需要满足二叉树的所有条件,然后有所改进,规定了左右子树的高度差不能超过1,如果插入数据导致高度差超过了1则自动进行调整,回复到平衡状态。这也是平衡二叉树名字的由来。

图一就是一颗平衡二叉树,图二根节点的左子树高度为0,右子树高度为5,高度差是5超过了1所以不是一颗平衡二叉树。

平衡二叉树查找效率要高于二叉树。

 

什么是B树?

由前面的推导我们可以看出要想查找,比较的次数最少,必须想办法降低树形结构的高度,不管是二叉树还是平衡二叉树,每个节点最多只能有两个子节点,这就注定了它的高度受限于子节点的个数,于是B树横空出世.

从上图可以看到B树的节点可以不止两个子节点,这样的好处就是树可以变得又矮又胖,矮胖的树是索引的最爱,用它做索引可以降低磁盘的IO.

B树中的每个节点根据实际情况可以包含大量的键值,数据和指针,上图所示为一个3阶的B树:

每点占用一个磁盘块的磁盘空个节间,一个节点上有两个升序排序的键值和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个键值划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,键值为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。

模拟查找关键字29的过程:

根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】

比较关键字29在区间(17,35),找到磁盘块1的指针P2。

根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】

比较关键字29在区间(26,30),找到磁盘块3的指针P2。

根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】

在磁盘块8中的关键字列表中找到关键字29。

分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作。由于内存中的键值是一个有序表结构,可以利用二分法查找提高效率。而3次磁盘I/O操作是影响整个B树查找效率的决定因素。

 

什么是B+树?

想想还有没有可能进一步优化,在B树中每个节点的内容由三部分组成:键值,指针,数据,而磁盘块的容量是有限的,并不是每次读取磁盘块都会取出里面的数据,只是在最后一次读取的时候才会取出里面的数据,能不能将数据只存储在叶子节点里面,非叶子节点只存储键值和指针呢?这样就能最大化的利用磁盘块空间,一个磁盘块也就能存更多的东西了,没错,B+树就是这么干的

假设在非叶子节点不存数据以后每个节点可以存储4个键值和指针,就变成了上图的B+树

B+树相对于B树有几点不同:

  1. 非叶子节点只存储键值和指针。
  2. 所有叶子节点之间都有一个链指针。
  3. 数据记录都存放在叶子节点中。

在B+树中因为叶子节点的键值是按顺序排列的所以进行键值的范围查找效率非常高。

在B+树中由于一个节点存储了更多的键值和指针,所以同样多的内容可以降低树的高度,减少磁盘io次数,从而提高效率。

数据库的索引分为聚集索引和非聚集索引,innoDb存储引擎中的聚集索引表中的数据按主键的顺序存放,它实际上就是按主键构建的一个B+树,叶子节点存放的是数据行记录。所以数据库中的数据实际上是索引的一部分。由于实际的数据页只能按照一个顺序存放,所以每张表聚集索引只能有一个。

非聚集索引的叶子节点中存放的是键值和主键值,所以通过非聚集索引需要先查找到主键值然后通过聚集索引查询到具体的数据,因此非聚集索引的效率要低于聚集索引。非聚集索引并不会影响到数据的存储顺序,所以非聚集索引可以存在多个。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/269943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信输入法来了,一起来体验一下吧

大家期待已久的微信输入法终于来了,不是内置于微信当中,而是一款独立应用的APP,今天小编带大家来体验一下微信输入,到底好不好用? 目录 1、安装 2、功能介绍 2.1、智能推荐公众号、视频号、小程序等 2.2、可直接发…

python2.6.6安装MySQL-python模块正确方法

Centos6.5 x64 系统python2.6.6安装MySQL-python模块 一、安装前准备 操作系统:centos6.5 x64 安装python和python开发工具   python python-devel 安装mysql-server和mysql开发工具   mysql-server mysql mysql-devel yum -y install mysql-devel libxml2 libx…

猿创征文 | Docker实战:Linux环境安装Tomcat安装步骤

目录 1.官网镜像版本查找 2、拉取tomcat镜像 3. 查看镜像是否下载成功

博客搬家

博客搬家 今天这篇博客只想向大家公布一件事,我的博客要搬家了,确切的说是我要同步我两个博客端的博客,原因主要有二: 我最初在网络上查资料主要看到的两个端有csdn 也有 博客园(我喜欢的一个大神在这)&…

猿创征文 | Docker笔记:Docker网络知识介绍

目录 1、docker网络介绍 2、测试容器和宿主主机的通信 2.1 宿主主机可以ping通 docker0

Zabbix的安装(源码安装)

zabbix3.0完全安装 安装zabbix首先需要安装ltmp(lnmp),这里的t是指tengine(taobao的nginx版本),安装教程见 http://www.ltmp.cc 安装的时候PHP选择5.4版本,因为zabbix3.0需要php5.4以上版本。 安…

WCF 服务端+客户端动态调用

最近在写WCF服务相关代码,把项目中用到的通讯框架做了下整理,以备以后自己记忆。 WCF服务端: 包含契约定义:WCF.Contract、契约实现:WCF.Service 以及宿主主程序:WcfServerHost 本DEMO 为了为了演示&#x…

动态区间第K大

整体二分。 主要需要注意的一点是&#xff0c;对于每个删除操作&#xff0c;若删除操作被算入贡献&#xff0c;则最开始的插入操作也一定会被算入&#xff0c;所以不必担心删除删错。 #include<cstdio> #include<algorithm> #include<cstring> using namesp…

Docker笔记:docker四种网络模式介绍

目录 1、docker网络模式分类 2、bridge 网桥模式 3、host 模式 4、container模式 5、none模式

Elasticsearch之分词器的工作流程

前提 什么是倒排索引&#xff1f; Elasticsearch之分词器的作用 Elasticsearch的分词器的一般工作流程&#xff1a; 1、切分关键词 2、去除停用词 3、对于英文单词&#xff0c;把所有字母转为小写&#xff08;搜索时不区分大小写&#xff09; 后续博客 Elasticsearch之停用词 转…

shell 1

换行符号 ctrlJBackspace ctrlHend-of-file ctrlD 1 背景知识2 入门 第一行 #! 空白符号被略过 可选项 注意此处的初级陷阱p37 shell基本元素 命令与参数 如果使用的使"&"而不是";"&#xff0c;则Shell将在后台执行其前面的命令&#xff1b;意味着&…

微信小程序把玩(二十六)navigator组件

微信小程序把玩&#xff08;二十六&#xff09;navigator组件 原文:微信小程序把玩&#xff08;二十六&#xff09;navigator组件navigator跳转分为两个状态一种是关闭当前页面一种是不关闭当前页面。用redirect属性指定。 主要属性&#xff1a; wxml <navigator url".…

docker笔记:docker容器通信参数 --link参数介绍

目录 1、link 参数作用 2、命令格式 3、link原理 4、测试案例 5、link参数注意事项