【转帖】MySQL索引
数据表如何用索引快速查找
索引是 排好序的快速查找的数据结构
索引存储在文件系统中
索引的文件存储形式与存储引擎有关
索引数据结构:可以是二叉树、红黑树、Hash表、B-Tree、B+Tree
1、二叉树
使用索引的如下图:(如果是使用二叉树结构)每一个节点都存放数据行的磁盘地址【快速定位到数据】

虽然索引不是使用的二叉树,而是使用B+Tree结构,为什么不使用二叉树呢?
如果索引是连续的数字,二叉树就会蜕变成链表,访问的速度还是和没加索引一样

这时再查找效率就变低了
2、红黑树
红黑树作为索引的数据结构呢,其实红黑树是二叉平衡树,到某个节点数值的绝对值超过2,就会重新排列(该节点不平衡),但是为什么索引还没 有选择红黑树呢,原因是树的高度比较高(一直是二叉),索引树的高度比较高,和磁盘进行IO操作比较多

3、BTree
BTree又叫多路平衡搜索树,就是一个节点开辟更大的空间,(横向)存放多个索引
- 叶子节点具有相同的深度,叶子节点的指针为空
- 节点中的数据从左到右递增排列

这样树的高度就解决了,横向存储更多,但是为什么不选择BTree呢,因为页节点有默认大小的,如果每个节点都存储数据data,这时页节点就存储的个数不多,这样会增加树的高度.
4、B+Tree
B+Tree对BTree做了点优化,非叶子节点不存data数据,一个节点MySQL底层叫做页节点(默认分配16KB大小)
SHOW GLOBAL STATUS like 'Innodb_page_size';
- 1


索引一般使用int 默认是8B,指针是存储下一个页节点的地址大小为6B,所以一个页节点可以存放 16KB /(6+8)B = 1170 个 高度为3 的可以存放 = 1170 * 1170 * 16 差不多两千万多
5、MyISAM存储引擎实现
MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求

创建一个存储引擎是MyISAM的test_MyISAM表

【注意】
MySQL8开始删除了原来的frm文件,并采用 Serialized Dictionary Information (SDI), 是MySQL8.0重新设计数据词典后引入的新产物
myIsam.MYD:存储表的数据信息
myIsam.MYI:存储表的索引信息(index)
从上面的索引中可以看到,通过索引查找数据,最后是定位到物理地址(MYD文件)所在的位置
比如通过where条件查询时,会判断是不是索引,如果是索引,每次查找时,把当前的页子节点从磁盘中(.MYI文件)加载到内存中【这是一个比较耗时的操作,该操作也是一次IO操作】,这也是典型的非聚集索引(索引文件和数据文件分离的)
6、InnoDB存储引擎实现
InnoDB存储引擎是MySQL默认存储引擎,InnoDB存储引擎提供了具有提交、回滚、崩溃恢复能得事务安全
聚集索引:数据和索引存放在一起
InnoDB存储引擎的表必须建立主键,建立了主键,主键就是聚集索引
聚集索引查找数据的图结构如下:

创建以InnoDB存储引擎的表test_InnoDB,查看表结构
在MySQL8就只有一个.ibd文件,之前的版本是有.frm文件的

数据和索引都存放在.ibd文件中,就如上图一样,主键索引(聚集索引)自带完整的数据,普通的索引是自带id主键,再通过id主键获取数据data
如图:先定位id主键值,再回表查询(通过id值查询–》聚集索引)

1)为什么建议InnoDB表必须建立主键,并且推荐使用整型自增主键?
如果不建立主键,数据库会找一个唯一区别的列作为主键,如果没找到就增加一个隐藏列rowid来维护索引(使用B+Tree),我们尽量节省MySQL的性能,不要它帮我们建立。
推荐使用整型的自增主键,因为如果使用字符串查询时是逐位比较每一位字符,比较慢
2)为什么非主键索引结构叶子节点存储的是主键值?
- 保持一致性
当数据库表进行DML操作时,同一行记录的页地址会发生改变,因此非主键索引保存的是主键值,无需要进行改变
- 节省存储空间
InnoDB数据本身就是汇聚到主键索引所在的B+Tree上了,如果普通索引还继续再保存一份数据,就会出现有多少索引就会存多少份数据
7、Hash表
索引也是可以设定位Hash表,但是使用不多

对索引的key进行hash计算确定数据存储的位置(数组下标位置),如果出现hash冲突时,通过链地址法解决冲突

- Hash索引无法被用来避免数据的排序操作
由于Hash索引中存放的是经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
- 但是Hash索引仅能满足 “=” ,“in” ,不支持范围查询
由于Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的Hash算法处理之后的Hash值的大小关系,并不能保证和Hash运算前完全一样。
还有Hash冲突问题,如果冲突很多维护代价很高
Hash索引不能利用部分索引键查询
对于组合索引,Hash索引在计算Hash值的时候是组合索引键合并后再一起计算Hash值,而不是单独计算Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash索引也无法被利用
- Hash索引在任何时候都不能避免表扫描
Hash索引是将索引键通过Hash运算之后,将 Hash运算结果的Hash值和所对应的行指针信息存放于一个Hash表中,由于不同索引键存在相同Hash值,所以即使取满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
- Hash索引遇到大量Hash值相等的情况后性能并不一定就会比BTree索引高
如果创建Hash索引,那么将会存在大量记录指针信息存于同一个Hash值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
上面的两点算是不选择Hash索引的原因
通过Hash索引怎么查找数据呢???
比如使用Hash索引时,查找数据,首先计算hash值,再到链表查询数值,在定位到物理地址,才算是查找成功
哈希碰撞很多时,查询还是会变的缓慢,因为必须要遍历链表中对应的所有数据行进行匹配,同样更新索引的效率也会受到影响,导致数据的新增、修改、删除速度变慢。
既然Hash索引是不支持范围查找,那么B+Tree是怎么范围查询的呢??
8、B+Tree的范围查找
叶子节点用指针连接,提高区间访问的性能

比如查找 范围在20-50的数据,首先查找20,之后通过20后面的指针指向后面的往后查找,直到查找到大于50的为止(通过这个叶子节点的指针可以看出,连续且自增的主键好处),使用主键自增的可以避免页节点的元素分裂导致范围查询效率低。
复合索引的最左前缀优化原则
对于复合索引,它的索引B+Tree是怎么样构建的呢?

联合索引首先按照第一个字段排序,如果第一个相同再按照第二个字段排序,依次类推
9、索引分类
1、主键索引
2、唯一索引
3、普通索引(辅助索引 或者 二级索引)
4、全文索引
5、组合索引
【转帖】MySQL索引的更多相关文章
- mysql索引需要了解的几个注意
板子之前做过2年web开发培训(入门?),获得挺多学生好评,这是蛮有成就感的一件事,准备花点时间根据当时的一些备课内容整理出一系列文章出来,希望能给更多人带来帮助,这是系列文章的第一篇 注:科普文章一 ...
- Mysql 索引原理(转自:张洋)
摘要 本文以MySQL数据库为 研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据 库支持多种索引类型,如 ...
- Mysql 索引需要了解的几个注意
索引是做什么的? 索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行.表越大,花费的时间越多.如果表中查询的列有一个索引,MySQL能快 ...
- 要想深入理解mysql索引?这16个点你必须要了解!
前言 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQ ...
- 深入MySQL索引
MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...
- MySQL 索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是 ...
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
- 【转】MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- [转]MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
随机推荐
- MySQL进阶篇:详解索引结构
2.2 MySQL进阶篇:第二章_二.二_索引结构 2.2.1 概述 MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种: 索引结构 描述 B+Tree索引 最常见 ...
- C++篇:第六章_指针_知识点大全
C++篇为本人学C++时所做笔记(特别是疑难杂点),全是硬货,虽然看着枯燥但会让你收益颇丰,可用作学习C++的一大利器 六.指针 (一)指针规则 两个指针不能进行加法运算,因为指针是变量,其值是另一个 ...
- 认识BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
本文分享自华为云社区<Spring高手之路13--BeanFactoryPostProcessor与BeanDefinitionRegistryPos>,作者: 砖业洋__ . 在Spri ...
- JerryScript:物联网开发者的得力工具
摘要:本文档以Linux开发环境及realview-pbx-a9开发板为例,简单介绍LiteOS上jerryscript命令的使用. 本文分享自华为云社区<Jerryscript-让开发者事半功 ...
- 中断操作:AbortController学习笔记
前端面试一般喜欢问: 请手写一个带取消功能的延迟函数,axios 取消功能的原理是什么? 如何中断请求fetch的原理分析和应用? 在看来<使用 AbortController 终止 fetch ...
- PPT 做出动态路线动画
https://www.iconfont.cn/ 插入,起点.终点,两图标 编辑顶点,调整路线 添加淡出动画,持续时间1秒 再添加直线 从上一项开始 效果选项中,选择自动翻转 计时 -> 期间 ...
- PPT 动画-制作一个倒酒
波浪往左上方,慢慢运动 数字 渐入 + 渐出 + 居中对齐 酒杯绘制 波浪绘制 上方的点全部设成[平滑顶点] https://getwaves.io/ 快速生成波浪[Office 2016 不支持插入 ...
- ubuntu下完全卸载重装docker教程
操作需在管理员权限下运行 卸载docker 1.删除docker的所有包 apt-get autoremove docker docker-ce docker-engine docker.io con ...
- 【JAVA基础】Mybatis示例
固定时间范围查询 <select id="selectPaidList" resultType="com.hand.htms.ifp.entity.IfpShipm ...
- java获取年月日、时间与区间、Sql获取年月日区间
SQL 获取时.日.周.月日期 因工作上常用到统计分析,需要用到具体的时间,故写于此 24小时: SELECT 0 AS hour UNION ALL SELECT 1 AS hour UNION A ...