深入理解Mysql索引底层数据结构与算法
索引是帮助MySQL高效获取数据的排好序的数据结构
索引数据结构对比
二叉树
左边子节点的数据小于父节点数据,右边子节点的数据大于父节点数据。
如果col2是索引,查找索引为89的行元素,那么只需要查找两次,就可以获取到行元素所在的磁盘指针地址。

如果col1是索引,查找索引为6的行元素,那么需要查找六次,就可以获取到行元素所在的磁盘指针地址,即得到了该索引为6的行元素。因此二叉树不适合存储单边增长的序列字段,近乎全表扫描获取数据。
红黑树
本质二叉树,属于二叉平衡树,jdk1.8 hashmap的底层实现;
存储大数据量,树的高度不可控, 数量越大,树的高度越高;
500w行数据,2的n次方=500w数据量, n是树的高度,也就是查询次数;
hash表
通过散列可以快速获取磁盘文件指针,对于指定索引查找文件非常快,但是对于范围查找没法支持。
B树
本质是多路二叉树;
叶节点具有相同的深度,叶节点的指针为空;
所有索引元素不重复;
节点中数据索引从左到右依次递增的;

B+树(B树的变种)
非叶子节点不存储数据,只存储索引(冗余)和指针,可以放更多的索引,树高降低 ;
叶子节点包含所有索引字段;
叶子节点比b树增加了指针连接;
叶子节点有双向指针链接(首尾子节点还通过指针连接),提高区间访问的性能,范围查找;

为什么mysql页文件默认16K?
MySQL每个B+树节点最大存储容量:16KB (指针+数据+索引)。假设我们一行数据大小为1K,那么一页就能存16条数据,也就是一个叶子节点能存16条数据;再看非叶子节点,假设主键ID为bigint类型,那么长度为8B,指针大小在Innodb源码中为6B,一共就是14B,那么一页里就可以存储16K/14=1170个(主键+指针)
那么一颗高度为2的B+树能存储的数据为:117016=18720条,一颗高度为3的B+树能存储的数据为:11701170*16=21902400(千万级条)
show global status like `Innodb_page_size`
因此,B+树存储大数据量的表也可以非常高效的获取数据,MySQL使用B+树作为索引的数据结构。
存储引擎
存储引擎最终作用于:表 ,不是数据库
在mysql的安装的根目录下,有一个data目录,里面存放的是所有表的数据。
- MyISAM:
MyISAM索引文件和数据文件是分离的(非聚集或稀疏);
主键索引和辅助主键索引存储类似;
frm文件:存储这张表的表结构
MYD文件:存储这张表的所有数据行
MYI文件:存储这张表的索引字段

- InnoDB(聚集):
表数据文件本身是按照B+tree组织的一个索引结构文件
frm文件:存储这张表的表结构
ibd文件:存储这张表的所有数据行和索引字段
聚集(聚簇)索引----叶节点包含完整数据记录

为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
- 首先,为了满足MySQL的索引数据结构B+树的特性,必须要有索引作为主键,可以有效提高查询效率,因此InnoDB必须要有主键。如果不手动指定主键,InnoDB会从插入的数据中找出不重复的一列作为主键索引,如果没找到不重复的一列,InnoDB会在后台增加一列rowId做为主键索引。
- 其次,索引的数据类型是整型,一方面整型占有的磁盘空间或内存空间相比字符串更少,另一方面整型比较比字符串比较更快速,字符串比较是先转换为ASCII码,然后再比较的。
- 最后,B+树本质是多路多叉树,如果主键索引不是自增的,那么后续插入的索引就会引起B+树的其他节点的分裂和重新平衡,影响数据插入的效率,如果是自增主键,只用在尾节点做增加就可以。
为什么非主键索引结构叶子节点存储的是主键值?
- 主键索引和非主键索引维护各自的B+树结构,当插入的数据的时候,由于数据只有一份,通过非主键索引获取到主键值,然后再去主键索引的B+树数据结构中找到对应的行数据,节省了内存空间;
- 如果非主键索引的叶子节点也存储一份数据,如果通过非主键索引插入数据,那么要向主键索引对应的行数据进行同步,那么会带来数据一致性问题。可以通过事务的方式解决,我们都知道使用事务后,就会对性能有所消耗。
联合索引
联合索引的底层存储结构长什么样?
定义联合索引(员工级别,员工姓名,员工出生年月),将联合索引按照索引顺序放入节点中,新插入节点时,先按照联合索引中的员工级别比较,如果相同会按照是员工姓名比较,如果员工级别和员工姓名都相同 最后是员工的出生年月比较。可以从图中从上到下,从左到右看,第一个B+树的节点 是通过联合索引的员工级别比较的,第二个节点是 员工级别相同,会按照员工姓名比较,第三个节点是 员工级别和员工姓名都相同,会按照员工出生年月比较。

还没关注我的公众号?
- 扫文末二维码关注公众号【小强的进阶之路】可领取如下:
- 学习资料: 1T视频教程:涵盖Javaweb前后端教学视频、机器学习/人工智能教学视频、Linux系统教程视频、雅思考试视频教程;
- 100多本书:包含C/C++、Java、Python三门编程语言的经典必看图书、LeetCode题解大全;
- 软件工具:几乎包括你在编程道路上的可能会用到的大部分软件;
- 项目源码:20个JavaWeb项目源码。

深入理解Mysql索引底层数据结构与算法的更多相关文章
- 深入理解MySQL索引底层数据结构
作者:IT王小二 博客:https://itwxe.com MySQL 索引相关的数据结构有两种,一种是 B+tree,一种是 Hash,那么为什么在 99.99% 的情况下都使用的是 B+tree索 ...
- Mysql索引底层数据结构与算法
索引是什么 索引是帮助MySQL高效获取数据的排好序的数据结构. 索引存储在文件里 补充知识: 磁盘存取原理: * 寻道时间(速度慢,费时) * 旋转时间(速度较快) 磁盘IO读取效率: * 单次IO ...
- MySQL索引之数据结构及算法原理
MySQL索引之数据结构及算法原理 MySQL支持多个存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.本文只关注BTre ...
- MySQL索引底层数据结构
一.何为索引? 1.索引是帮助数据库高效获取数据的排好序的数据结构. 2.索引存储在文件中. 3.索引建多了会影响增删改效率. (下面这张图为计算机组成原理内容,每查询一次索引节点,都会进行一次磁盘I ...
- 深入理解 MySQL 索引底层原理
https://mp.weixin.qq.com/s/qHJiTjpvDikFcdl9SRL97Q
- 理解MySQL——索引与优化
转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...
- 深入理解mysql索引
深入理解mysql索引 1 深入理解索引 1.1 索引基础理论知识: 1.2 B+树索引 1.3 哈希索引 1.4 理解B+树.哈希索引结构及区别: 1.5 理解常见索引的基本概念:主键索引.唯一索引 ...
- 数据库索引使用数据结构及算法, 及MySQL不同引擎索引实现
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- Mysql高手系列 - 第22篇:深入理解mysql索引原理,连载中
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第22篇. 背景 使用mys ...
随机推荐
- HDU5521 Meeting(dijkstra+巧妙建图)
HDU5521 Meeting 题意: 给你n个点,它们组成了m个团,第i个团内有si个点,且每个团内的点互相之间距离为ti,问如果同时从点1和点n出发,最短耗时多少相遇 很明显题目给出的是个无负环的 ...
- 【dfs基础讲解及例题】
定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种. 接下来因为懒得去找大段大段深奥的材料 所以就是一些个人的理解. 所谓深搜,是相对于广搜(只是第一篇)来说的.深 ...
- requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))【已解决】
问题: 跑python自动化时出现报错如下图 解决: requests请求时,后面加上参数:stream=True. 参考外国小哥:https://stackoverflow.com/questio ...
- golang http json http://www.alexedwards.net/blog/golang-response-snippets
http://www.alexedwards.net/blog/golang-response-snippets https://gist.github.com/andreagrandi/97263a ...
- NOIp2018普及组T3暨洛谷P5017 摆渡车:题解
题目链接:https://www.luogu.org/problemnew/show/P5017 emm,这次的真的不简单的,T3比T4难? 醉了... 蒟蒻肯定没有其他大佬讲的好啊,但肯定尽力,真的 ...
- E11000 duplicate key error index
E11000 duplicate key error index mongodb插入报错,重复主键问题,有唯一键值重复 一般使用collection.insertOne(doc);插入一条已存在主键的 ...
- python+selenium实现163邮箱登陆—iframe动态ID定位 及常用定位方法
今天发现之前的登录163邮箱脚本定位不到iframe了,原因是iframe拼接了动态ID,修改后的脚本如下: from selenium import webdriver driver = webdr ...
- MyBatis-Plus 使用说明介绍
先看一下和MyBatis 不同点说明: @GetMapping("/select_sql") public Object getUserBySql() { User user=ne ...
- CGI,WSGI区别
WSGI 参考link:https://jingtyu.gitbooks.io/learning-openstack/content/351-usgi.html(本人的gitbook) 个人理解: w ...
- C#加密解密(AES)
using System; namespace Encrypt { public class AESHelper { /// <summary> /// 默认密钥-密钥的长度必须是32 / ...