当前位置: 首页 > news >正文

图解Mysql索引的数据结构!看不懂你来找我

听说微信搜索《Java鱼仔》会变更强哦!

本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦

(一)关于索引

索引是帮助Mysql更加高效获取数据的一种数据结构,索引的使用很简单,但是如果不能理解索引底层的数据结构的话,就谈不上去优化索引了。

(二)B+树

Mysql的索引用的是B+树,他具有这样的几个特点:

1、数据都存储在叶子节点中、非叶子节点只存储索引

2、叶子节点中包含所有的索引

3、每个小节点的范围都在大节点之间

4、叶子节点用指针相连,提高访问性能,比如条件是>或者<的查询就可以直接按指针找(Mysql中的B+树叶子节点中的指针是双向指针)

B+树的数据结构如图所示,首先非叶子节点只存储索引,且每个指针所指向的节点最左边的索引都是该指针对应的索引值,比如头节点的第一个索引值8,指向的非叶子节点的第一个索引值也是8。

(三)为什么索引这么快?

索引可以支撑千万级表的快速查找,为什么呢?下面就来解释一下:

show GLOBAL STATUS like 'Innodb_page_size'

在这里插入图片描述

在Innodb中,默认的innodb_page_size大小为16kb,这就相当于上面每一个节点的大小默认情况下是16kb。一个索引值的大小为8B,索引后的指针所占大小为4B,因此可以解算出一个节点中大约可以存储1170个索引。

对于叶子节点,由于存储了数据,我们可以大方地估计每个数据的大小为1kb,相当于在叶子节点中每个节点可以存储16个数据

这样就可以计算出一个三层的B+树结构的索引一共可以存储1170117016=2190万条数据,这就意味着只需要三次磁盘IO,就可以检索两千万条数据,由此可见索引可以支撑千万级表的快速查找。

在这里插入图片描述

(四)Innodb索引的实现

Mysql中的存储引擎有InnodbMyisam两种,两种索引的实现底层虽然都是B+树,但是实现形式还是略有不同。

Innodb属于聚簇索引,即叶子节点包含了完整的数据记录。下面这张图是innodb的主键索引,所有的数据都放在叶子节点中。

在这里插入图片描述

Innodb要求表必须有主键,并且推荐使用整型的自增主键,这也和他索引的实现有关,使用整型可以更好的进行B+树的排序,同时采用自增的方式可以在插入数据时将数据插入到最后一个节点的后一个,而不用对已产生的索引拆分。

非主键索引和主键索引略有不通,非主键索引的叶子节点存储的是主键的key值

在这里插入图片描述

采用这种方式保持了数据的一致性,当新增一条数据时,只需要在主键索引处修改数据即可,而不会出现每个索引各自维护的情况。第二个优势是节省了存储的空间,数据只需要保存一份即可。

(五)MyIsam索引的实现

Myisam索引文件和数据文件是分离的,在MyIsam存储引擎中,新建一张表后会在磁盘中增加三个文件:

在这里插入图片描述

.frm 文件存储的是表结构,.MYI文件存储的是B+树的索引表,MYD存储的是数据,我通过下面这张表展示MyIsam索引:

在这里插入图片描述

(六)总结

关于数据库的索引,绝对是工作中常用,面试常考的问题,他太重要了。理解索引底层数据结构更加重要,这是后续优化的基础,好了,我们下期再见!

相关文章:

  • 如何用Java写一个规范的http接口?
  • Getting started with Java EE 8 MVC(1)
  • 产品经理问我:手动创建线程不香吗,为什么非要用线程池呢?
  • 将桌面上的硬盘移除
  • 白话Mysql的锁和事务隔离级别!死锁、间隙锁你都知道吗?
  • Jquery datatables 使用方法
  • 基于SpringBoot实现文件的上传下载
  • 作为一个后端开发,你需要了解多少Nginx的知识?
  • CAShapeLayer(持续更新)
  • 一个成熟的Java项目如何优雅地处理异常
  • UITableView分页
  • 分布式集群环境下,如何实现每个服务的登陆认证?
  • 【中亦安图】Oracle内存过度消耗风险提醒(6)
  • 你知道JWT是什么吗?它和Session的区别又在哪里?
  • hadoop家族成员
  • .pyc 想到的一些问题
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • github指令
  • MYSQL 的 IF 函数
  • Python 基础起步 (十) 什么叫函数?
  • redis学习笔记(三):列表、集合、有序集合
  • sublime配置文件
  • 仿天猫超市收藏抛物线动画工具库
  • 关于使用markdown的方法(引自CSDN教程)
  • 基于web的全景—— Pannellum小试
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 微信小程序设置上一页数据
  • 一个JAVA程序员成长之路分享
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • (07)Hive——窗口函数详解
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (笔试题)分解质因式
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (十六)Flask之蓝图
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)fock函数详解
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (轉貼) UML中文FAQ (OO) (UML)
  • .aanva
  • .net程序集学习心得
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .NET实现之(自动更新)
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • @ModelAttribute注解使用
  • @test注解_Spring 自定义注解你了解过吗?
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [C#]科学计数法(scientific notation)显示为正常数字
  • [DevEpxress]GridControl 显示Gif动画