mysql总结笔记 -- 索引篇
索引的作用
索引是用来高效的获取数据的 排好序 的 数据结构,如果没有索引,可能会导致查询某一条记录的时候遍历整张表;所以适当的索引可以大大的提升检索速度;
索引的数据结构
- 二叉树
假如说我们有一列数据是0-6,我们使用的是二叉树进行存储的话,此时我们可以看到二叉树的存储方式为下图:

- 我们可以看到二叉树如同链表的形式存储了完整的数据,这时我们假设要查值为6的数据,我们就需要七次IO操作才能拿到数据结果;试想假如我们数据过多这时候查询数据就会非常的慢,就相当于全表扫描;
- 所以我们的mysql数据库,肯定是不会用这种数据结构来存储数据;
- 红黑树

- 同样是的存储数据0-6,这时我们会发现红黑树在每次存储的时候,都会动一下;目的就是为了平衡,本质上和二叉树是一样的这里只是多了一步平衡操作,所以红黑树又称平衡二叉树;
- 在查询上我们也可以看到,相比于二叉树来说它做了平衡,树层级相对来说会变小,在我们查找数据的时候IO操作也相对来说少些了;
- mysql也没用这种数据结构,其实我们也应该想的到,一方面数据多了节点一直往下分散还是可能会很多;另一个方面每变动一个节点的时候树都会做平衡花销不可估量;
- hash表
hash 我们知道查找数据的复杂度为O(1)
- 对索引的key进行一次hash计算就可以定位出数据的存储位置;
- 很多时候hsah比b+tree更高效,因为只要hash到对应的key值就能拿到元素;
- 只能满足 "=", "in" 不能范围查找;
- 会存在hash冲突问题(如上图key=2的数据,同一个key存储了两个值,在拿数据的时候会定位到2的数据,然后一次比对拿符合条件的数据);
因为本质的复杂度为O(1)特性速度一般会很快,但是我们工作中一般用的不是很多,最根本也是最重要的原因是不支持范围查找,还存在hash冲突的问题;
- b-tree
- 通过上边你的二叉树红黑树我们可以发现都有个共同的问题,就是数据多了层级都会很深查数据都会很慢;这里b-tree就做了一个改进,每个节点可以横向扩展存更多的数据,这时树的层级就会明显变少,减少磁盘IO操作;如下图:
- 上图我们可以看到,节点横向扩展可以存储更多的节点数据, 也就是说一次IO操作我们可以那倒更多的数据,如果不存在时我们就进行下一个节点查询; 我们也可以看到每个索引元素都同时存储了data数据, 也就是说当我们找到索引是可以马上拿到data的; 节点中的数据索引从左到右依次递增;
- mysql也不是用的这种数据结构,毕竟还是存在一些弊端如:
- 每个索引节点都存储了data数据,每个节点的存储空间有限,这时层级也会存在深的情况;
- 没有相邻的双向指针,当范围查找时都需要节点挨个筛选,不利于范围查询;
- 当我们发生修改删除数据时,也会伴随着树节点的变动,从而造成性能上的损耗;
- b+tree
mysql用的就是这种数据结构, 其实b+tree是b-tree的一个变种大概还是一样做了些改进:
- 非叶子节点不存储data数据, 只存储索引,相比于b-tree可以放更多的索引;
- 叶子节点存有data和所有节点的索引字段;
- 叶子节点之间用指针相连接,提升了区间访问的性能;
- 节点中的索引从左到右依次递增;
- 删除数据时只删除叶子节点,非叶子节点不变,不影响整个树的结构;
补充 树中每个节点可以存储16Kb的数据
可以用下方sql查询show GLOBAL STATUS like 'Innodb_page_size'
那我们来计算下每个节点大概能存储多少数据:
假设我们用bigInt类型当自增主键的话,bigInt也就是上图的索引元素占8个字节,磁盘地址指针mysql默认分配6个字节;也就是说我们一个节点可以存储16Kb/(8+6)B约等于1170个元素;叶子节点因为要存储data元素所以元素个数可能会相对其他节点少,我们假设只存储了15个元素,那么我们一个三阶的树就可以存储 1170117015 约 两千万条数据,也就是说两千万的数据我们只需要三次IO就能拿到值(mysql本身也有做优化非叶子节点会被加载到内存中,也就是说我们取值可能就一次IO就能拿到值,速度会大大提升);
MyISAM 存储引擎
MyISAM 存储引擎中数据存储分三个文件存储分别为 .frm结构 .MYD数据 .MYI索引 三个文件,即为非聚集索引;
上图我们可以看到索引和数据存在不同的文件中,当我们检索数据的时候是先找MYI文件定位到引用地址,再去MYD中拿数据的;
InnoDB 存储引擎
InnoDB 存储引擎中数据和索引是放在同一个文件中分别为 .frm结构 .idb 两个文件,即为 聚集索引;
- InnoDB 中每个叶子节点存储整条数据的所有字段(如叶子节点索引18,存储的是数据 77 Alice);
- 表文件本身就是一个b+tree树组织的索引结构文件;
- 由于主键和数据都在同一个文件中,所以InnoDB必须要有一个主键,并且建议为自增主键(如果不设主键则mysql会自动的在你的列表中找到一个符合条件的唯一索引字段,如果没有mysql将添加一个类似 ROW_Id 充当主键);
- 非主键索引结构的叶子节点存储的是主键值,是为了实现一致性,节省存储空间;
聚集索引和非聚集索引哪个效率更高
非聚集索引查询到索引值之后,只是拿到了索引所在行的磁盘文件地址,需要通过这个地址再进行一次I/O操作;
聚集索引读取到叶子节点索引值之后,即那到了索引所在行的完整的数据内容,不需要额外的I/O操作;
工具辅助
动图树模拟地址:https://www.cs.usfca.edu/~galles/visualization/BST.html;
动图制作工具:GifCam工具;
mysql总结笔记 -- 索引篇的更多相关文章
- 数据库MySQL学习笔记高级篇
数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...
- mysql优化之索引篇
对mysql优化是一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引.主键索引.唯一索引unique.全文索引] c: 分表技术(水平 ...
- Mysql学习笔记—索引
一.什么是索引 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...
- MySQL学习笔记Windows篇<一> Welcome to MySQL
MySQL安装完毕后没有图形化操作界面,图形化管理界面需要另行安装,个人比较喜欢Navicat,界面更像SQLserver: 此篇学习笔记所有操作均使用命令行中完成: 1.开启/停止服务 使用MySQ ...
- MySQL学习笔记——索引和视图
索引(index)和管理索引 模式中的一个数据库对象 作用:在数据库中用来加速对表的查询 创建:自动在主键和唯一键上面创建索引 通过使用快速路径访问方法快速定位数据,减少了磁盘的I/O 与表独立存放, ...
- 【笔记】MySQL学习之索引
[笔记]MySQL学习之索引 一 索引简单介绍 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 普通 ...
- mysql那些事之索引篇
mysql那些事之索引篇 上一篇博客已经简单从广的方面介绍了一下mysql整体架构以及物理结构的内容. 本篇博客的内容是mysql的索引,索引无论是在面试还是我们日常工作中都是非常的重要一环. 索引是 ...
- 精通MySQL之索引篇,这篇注重练习!
老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...
- Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)
转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问对于可以静态化的页面,尽可能静态化对一个动态页面中可以静态的局部,采用静态化部分数据可以生成XML,或者文本文件 ...
随机推荐
- Markdown随时记录
Markdown学习 推荐文本编译器 Typora 标题(支持六级) 一级标题:# + 空格 + 内容 二级标题:## + 空格 + 内容 三级标题:### + 空格 + 内容 . . . 字体 粗体 ...
- Sentinel之流控规则
在上文Sentinel流量防卫兵中讲到了Sentinel入门以及流控规则一小部分,而Sentinel还有以下规则: 熔断降级规则 热点参数规则 系统规则 黑白名单规则 本文要讲的是流控规则 流量控制规 ...
- 设计风格之REST
一.简介 REST简介 REST 是英文 representational state transfer(表象性状态转变)或者表述性状态转 移;Rest 是 web 服务的一种架构风格;使用 HTTP ...
- Linux下安装中文字体
目录 一.Centos系列 二.Ubuntu系列 一.Centos系列 1.安装字体库 yum -y install fontconfig 2.添加中文字体,建立存储中文字体的文件夹 mkdir /u ...
- Python连接MySQL数据库获取数据绘制柱状图
一.Python通过pymysql包获取MySQL数据库中的数据(没有对应包的可以通过pip install pymysql 安装对应的包) import matplotlib.pyplot as p ...
- vue双向绑定和深浅拷贝
现象描述: vue 在使用的时候,当table绑定了某个data的时候.假如某个el-table-column下面的有个方法传参(data.row),然后在方法中用一个obj=data.row.(这里 ...
- 数据类型Table.TransformColumnTypes(Power Query 之 M 语言)
数据源: 任意数据源 目标: 设置适合的数据类型 操作过程: 选取指定列>[主页]>[数据类型]>选取 选取指定列>[转换]>[数据类型]>选取 选取指定列> ...
- CF938B Run For Your Prize 题解
Content 有两个人,一个在 \(1\) 处,一个在 \(10^6\) 处,在他们之间有 \(n\) 个奖品,第 \(i\) 个奖品在 \(a_i\) 处.一开始在 \(1\) 处的人每秒可向右移 ...
- java IO操作和计算操作:工作内存和主内存 volatile关键字作用;原子操作对象AtomicInteger ....
应该停止但无法停止的计算线程 如下线程示例,线程实例中while循环中的条件,在主线程中通过调用实例方法更新后,while循环并没有更新判断变量是否还成立.而是陷入了while(true)死循环. i ...
- 金山云 KS3 Python SDK 多线程并发上传文件;下载断点续传 参考脚本
并发上传 基于py自带模块 concurrent.futures import ThreadPoolExecutor #!/usr/bin/env python3 # -*- coding:utf-8 ...





