mysql索引底层图_MySQL索引底层数据结构
一、何为索引?
1、索引是帮助数据库高效获取数据的排好序的数据结构。
2、索引存储在文件中。
3、索引建多了会影响增删改效率。(一张表最多允许建16个索引)
(下面这张图为计算机组成原理内容,每查询一次索引节点,都会进行一次磁盘IO读取,即要寻道和旋转)
二、MySQL索引结构为什么是B+树?
MySQL 建索引可使用的数据结构有B+树和Hash两种,但是Hash用得很少, 优点是可以快速定位到某一行,缺点是不能解决范围查询问题。
对于如果不需要使用范围查询、只需要精准查询的场景,可以使用Hash索引方法,比如查电话号码。
再说说主流的索引方法B+树,先说下为什么不用别的树结构,再说为什么用B+树。
1、为什么不用二叉树?
如果碰到下面这种单边增长的极端情况,查找节点4和顺序查找没区别。(这种特殊情况的二叉树等同于链表,时间复杂度为O(n))
2、为什么不用红黑树?
红黑树是一颗平衡二叉树,数据量大的时候,树的深度也很深,如果树的深度有20层,而查找的数据在叶子节点,就要进行20次IO操作,性能低。
3、为什么不用B树?
B树的特点:
叶子节点具有相同的深度
叶子节点的指针为空
叶子节点中的数据key从左到右递增排列
其实B树就是在横向做了文章,一个节点可以存储更多数据(大节点包含很多小节点),这样相对来说,深度就会变浅。
提问:横向的节点怎么查,比如说查找上图中的节点77?
从磁盘中把大节点查找出来,把这个大节点加载进内存中,节点77实际上是在内存中查找的,在内存中做的是随机访问,速度很快,跟磁盘的寻道和旋转相比的话,基本可以忽略不计。
提问:为什么不可以让B树横向的度无限增大,这样不就深度为1,查找不就更快了?(度的含义:节点的数据存储个数)
本来是想通过一次IO操作把一个大节点加载进内存,如果一个大节点的数据量太大的话, 则内存和硬盘一次交互没办法交换那么多数据,假设一次只能交换1页(4k)的数据(有上限,也有可能是几十页,和计算机硬件有关),意味着CPU去硬盘上做一次IO操作只能取1页的数据,那么当一个大节点的数据量太大时,仍要进行多次IO操作。因此,度是有上限的,MySQL会根据计算机硬件自动进行度的优化,一个大节点通常为1页空间。
4、为什么使用B+树?(B+树是B树的变种,索引做了冗余,存了多份,但是没关系,索引只占很小空间,比如下图中的15节点)
B+树的特点:
非叶子节点不存储data,只存储key,可以增大度(相比B树,B+树的深度更浅)
叶子节点不存储指针
顺序访问指针,提高区间访问的性能(实际上是双向指针)
提问:为什么说B+树可以增大度?
因为非叶子节点只存储索引一个值,不存储data(B树会存储data),而大节点大小是确定的,因此大节点就可以存储更多的数据,即度可以变得更大。这样既保证度可以达到最大,又保证一个大节点通过一次IO操作可以加载进内存。(非叶子节点度更大,深度更浅,只有非叶子节点才影响查找次数,叶子节点是最后一次查找,对总的查找次数是没有影响的,因此把data全部移到了叶子节点)
提问:为什么叶子节点之间还需要用指针?(一个大节点的尾节点和下一个大节点的头节点之间的指针连接)
方便范围查询。比如查找上图中key>18,如果没有指针会非常麻烦,必须从头开始查找,如果有指针,则可以直接遍历key>18的叶子节点(链表)。
B+树索引的性能分析:
一般使用磁盘I/O次数评价索引结构的优劣
预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存
局部性原理:当一个数据被用到时,其附近的数据也通常会立马被使用
B+树的大节点大小设为等于一个页,每次新建大节点直接申请一个页的空间,这能保证一个大节点物理上也存储在一个页里,大节点载入只需一次IO操作
B+树的度d一般会超过100,因此高度h非常小(一般为3~5之间)
三、MySQL底层是怎么用B+树来存储数据的?
MySQL有两种常见的存储引擎:InnoDB(默认)、MyISAM(用得少,在MySQL8.0中被废弃掉了),存储引擎范围是表级别的。
1、MyISAM索引实现(非聚集)
索引文件和数据文件是分离的
索引结构的叶子节点value存储的是文件指针。
.frm是表结构文件,.MYD是数据文件(MyISAM Data),.MYI是索引文件(MyISAM Index)。
MyISAM主键索引查找流程:先通过.MYI文件找到对应索引的文件指针,再根据文件指针去.MYD文件中定位对应的那行数据。
MyISAM普通索引查找流程:和主键索引查找流程一致。
2、InnoDB索引实现(聚集)
数据文件本身就是索引文件
表数据文件本身就是按B+树组织的一个索引结构文件
聚集索引的叶子节点包含了完整的数据记录
表必须有主键,且推荐使用整型的自增主键
普通索引结构叶子节点存储的是主键值
.frm是表结构文件,.ibd是数据和索引文件(InnoDB Data)
InnoDB主键索引查找流程:通过.ibd文件找到对应的索引,索引的value即为那行对应的完整数据。
InnoDB普通索引查找流程:通过.ibd文件找到对应的索引,索引的value即为那行对应的主键的值,再根据主键值去主键索引树中找到对应的行数据。
提问:聚集索引和非聚集索引的区别?
聚集索引:表中那行数据的索引和数据都合并在一起了。
非聚集索引:表中那行数据的索引和数据是分开存储的。
提问:为什么InnoDB表必须有主键?
因为整个数据文件本身就是按照B+树组织的一个索引文件,所以必须要有主键(建InnoDB表时不指定主键,默认会从表字段中选一列作为唯一主键,如果不存在这种字段,则后台默认生成一个长整型主键字段,MyISAM可以没有)。
提问:为什么推荐使用整型的自增主键?
提高查询性能。如果是使用UUID作为主键,第一,UUID长度很长,会浪费存储空间,第二,UUID是字符串类型,比较大小要查找ASCII码表,查找速度没有整型int查找速度快,第三,UUID是随机生成无序的字符串,当数据插入时,有很大可能会导致节点位置移动,还可能造成很多其他节点位置移动,简单来说就是位置打乱了。 如果使用整型的自增主键,新插入的数据都会连续的插入到磁盘的物理空间。
提问:为什么InnoDB普通索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
如果普通索引的value也存数据,那么当往有主键索引和普通索引的表中插入数据时,索引结构中key对应的value要存储两份数据,增加维护成本。
单值索引:只有一个索引,如(id),size=1
联合索引:多个索引合起来作为一个联合索引,如(id,name),size>1(单值索引是联合索引size=1的特例)
提问:联合索引的底层数据结构长什么样?
(叶子节点key是联合索引值,value是除联合索引以外一行记录其他字段的完整数据)
先比较id,如果id相等,再比较name,如果name也相等,则再比较date。(索引最左前缀原理,后面索引优化随笔会讲解)
mysql索引底层图_MySQL索引底层数据结构相关推荐
- mysql b tree图_MySQL索引--B-Tree(B+Tree)图文详解
看了很多关于索引的博客,讲的大同小异.但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引....或许有很多人和我一样,没搞清楚概念就开始研究B-Tree,B+Tree等 ...
- mysql索引原理传送门_MySQL索引底层实现原理
索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之一. ...
- mysql设置索引树长度_MySQL索引-B+树
索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据. 索引最形象的比喻就是图书的目录了.注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 ...
- mysql索引实现原理_Mysql索引原理
1.二分查找法 二分法,也叫二分查找法,是一种高效的查找算法. 如下一个有序数列,如果我们需要从中找到1这个元素,这个过程需要查找几次? [1,2,3,4,5,6,7,8,9,10] 对于这个数列查找 ...
- mysql索引优化分析_MySQL索引优化与分析(重要)
建表SQL CREATE TABLE staffs ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR (24) NULL DEFAULT '' COM ...
- mysql 二叉树表设计_Mysql 索引模型 B+ 树详解
一.认识二叉树 首先,在了解 mysql 中的 B+ 树之前,我们需要搞懂什么是二叉树.二叉树是一种常见的非线形数据结构,数据是以一对多的形态组织起来的,我画了一张图来帮助你理解: 在二叉树中,有一种 ...
- mysql 索引生命周期_MYSQL 索引(一)--- 简介
简介 Mysql 官方定义 : 索引(Index) 是帮助 Mysql 高效获取数据的数据结构. 索引的目的在于提交查询效率,可以类比字典.简单理解为 "排好序的快读查找数据结构" ...
- mysql b 树 锁_mysql索引B+树、MVCC、锁一文搞懂
1.innodb索引 innodb是页存储,一页是16K. 一个表的行数据都放到页里,单页都是单链表递增排序. 每个页之间都是双向链表保存.该页标记成数据页. 根据id查询时,也不知道在哪个数据页上. ...
- mysql索引条件下推_MySQL 索引条件下推优化
一 什么是"索引条件下推" "索引条件下推",称为Index Condition Pushdown (ICP),这是MySQL提供的用某一个索引对一个特定的表从 ...
最新文章
- Python中怎么判定一个List里面的元素是不是全部一样
- OpenCV之gpu 模块. 使用GPU加速的计算机视觉:GPU上的相似度检测(PNSR 和 SSIM)
- dom定义了访问html文档对象的,HTML DOM (文档对象模型)
- win7win10 配置wlan热点
- Nova虚拟机启动提示libvirtError
- 数据结构:链表(c语言)
- 才27岁,北大博士不幸离世
- codeigniter mysql查询_php – CodeIgniter MySQL查询不起作用
- 蔡高厅老师 - 高等数学-阅读笔记 - 01 - 前言、函数【视频第01、02、03、】
- 基于Xilinx Spartan-7 FPGA实现AD7606-8接口
- Python-Matplotlib 12 多图figure
- 支付宝小程序框架分析
- xwt100编程器使用方法与xtw100没有找到编程器解决办法
- 使用 jszip 实现.zip文件解压后上传
- 基于GPT2实现考公申论文章生成
- 如何抢功,甩锅,立于不败之地???
- 学数答题160912-导数极值点偏移
- 中小学数学卷子自动生成程序
- 20191025 前端开发日报
- Centos7 设置开机自启的几种方式
热门文章
- Extension project: 404 Not Found for resources/cus/crm/notes/ext/Component-dbg.js
- 使用application log 分析navigation target解析错误
- SAP CRM interaction center呼叫中心的一些性能问题的分析
- How AET fields are retrieved from backend
- ABAP Business switc和business function简介
- Java Spring实现原理研究之Servlet initialization初始化过程
- 前端开发神器Sublime里如何设置JSlint
- SAP Cloud for Customer的前端框架是如何基于SAP UI5框架开发的
- SAP CDS view性能调优的一些准则和例子
- python 连通域_连通域的原理与Python实现