MySQL索引底层原理理解以及常见问题总结
目录
- 二叉查找树为索引
- 红黑树为索引
- B树作为索引
- B+树作为索引
- MyISAM存储引擎索引实现
- InnoDB存储引擎索引实现
- 常见问题
- 聚集索引与非聚集索引
- InnoDB基于主键索引和普通索引的查询有什么区别?
- InnoDB主键索引为何是整型的自增主键
- 何时使用业务字段作为主键呢?
- 哈希与B树
- “N叉树”的N值在MySQL中是可以被人工调整的么?
二叉查找树为索引
二叉树的key为col2,value为索引所在行的磁盘地址。
但如果拿col1来作为key的话,会发现二叉搜索树退化成链表。
红黑树为索引
仍然以col1作为索引key,发现找6只需要查找3次。比二叉查找树更加合适一点
当表中有1百万行数据时,这棵树的高度会越来越大。如果我们查找的元素在叶子节点,查找次数会非常多。
B树作为索引
可以在树的横向上做文章,每个节点原本只存储一行数据的地址,现在可以修改为存储多行数据。因为树的高度越多说明IO操作越多,导致与磁盘的交互越多。
B树:
叶节点具有相同的深度,叶节点的指针为空。
所有的索引元素不重复
节点中数据索引从左到右递增排列
B+树作为索引
B+树
非叶子节点不存储data,只存储索引,这样可以放更多索引
叶子节点包含所有索引字段。
叶子节点用指针连接,提高区间访问性能。
也就是说在叶子节点存储了完整的元素,然后把一些处于中间位置的索引元素提取出来,作为非叶子节点。
MySQL设置默认节点大小为16kb,一个bigint为8byte,一个指针为6byte。所以一个节点最多能存16kb/14b = 1170。
再假设叶子节点一个元素占空间大小为1kb。
如果全部节点存储了满了,h = 3的时候一共能够存储1170 * 1170 * 16 = 21902400;这样可以存两千多万个数据了。
以下面为例:
注意,整个树都放在磁盘中,每次load一个节点进入内存。一般来说,先从根节点开始load。
我们现在要找6。比对根节点的3,6大于3,向右比较,发现6大于5,于是从5右边的指针找到下面一层的节点.
然后把这一层的节点从磁盘里面load到内存中。
我们还可以看到最底层的节点之间会有链表相连。
MyISAM存储引擎索引实现
注意,存储引擎是用来形容数据库中的表的。
MyISAM索引文件和数据文件是分离的。
我们使用查询语句:
select * from ... where Col1 = 49;
首先查找是否是索引字段,如果是就从MYI文件中的B+树里面去定位到这个元素。key存储的是索引元素,data存储的是索引元素所在的那一行的磁盘地址指针。拿到指针后去MYD文件定位。
InnoDB存储引擎索引实现
索引和数据放到了同一个文件中:.ibd文件。
叶节点包含了完整的数据记录,而不只是一个地址指针。
常见问题
聚集索引与非聚集索引
InnoDB就是聚集索引,索引和数据文件合在一起。
MyISAM是非聚集索引,索引和数据文件分离。
非聚集索引要查找两次,一次找到指针地址,一次根据指针地址找具体数据。
聚集索引只需要查找一次,直接找到具体数据,所以效率要更高。
InnoDB基于主键索引和普通索引的查询有什么区别?
如果语句是 select * from T where ID=500,即主键查询方式,则只需要搜索 ID 这棵 B+ 树;
如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。
也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。
InnoDB主键索引为何是整型的自增主键
自增主键的使用,关于存储和性能
InnoDB必须要有主键,而且推荐使用的是整型的自增主键。
因为数字好建立索引,方便比较,而且相比较于字符串类型,占用的空间更小。
关于自增:由于底层叶子节点是递增排列的,如果此时主键是递增的,那么新插入的元素就显然在叶子节点的最右边。
如果主键不是递增的,插入一个新的元素可能就会在叶子节点链表中间某处。B+树的结构调整就十分巨大了,可能上层的非叶子节点的索引值要修改。
例如这里我们插入8
树的结构发生了很大变化,直接裂开。
自增主键的插入数据模式,每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点的分裂。
何时使用业务字段作为主键呢?
只有唯一的索引,而且该索引为唯一索引。由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小的问题。
直接将这个索引设置为主键,可以避免每次查询需要搜索两棵树。
哈希与B树
哈希查找某个key很快,但是不支持范围查找。
B树用到范围查找就很方便了。叶子节点从左到右是一个递增的趋势。并且叶子节点之间通过指针相连,所以不需要再返回到上层索引中寻找。如果我们要找大于20的元素,那么只要在最底层,20元素的右边进行遍历即可。
如果是小于某个元素的情况,就是从底层叶子节点的左边开始,一直包含到边界即可。
“N叉树”的N值在MySQL中是可以被人工调整的么?
1, 通过改变key值来调整
N叉树中非叶子节点存放的是索引信息,索引包含Key和Point指针。Point指针固定为6个字节,假如Key为10个字节,那么单个索引就是16个字节。如果B+树中页大小为16K,那么一个页就可以存储1024个索引,此时N就等于1024。我们通过改变Key的大小,就可以改变N的值
2, 改变页的大小
页越大,一页存放的索引就越多,N就越大。
数据页调整后,如果数据页太小层数会太深,数据页太大,加载到内存的时间和单个数据页查询时间会提高,需要达到平衡才行。
MySQL索引底层原理理解以及常见问题总结相关推荐
- MYSQL索引底层原理
MYSQL索引底层原理 1. 索引的本质 索引是帮助MYSQL高效获取数据的排好序的数据结构. 索引一般以文件形式存储在磁盘上. 2. 按索引的分类 2.1. 按字段约束分类 2.1.1. 普通索引 ...
- 深入理解 MySQL 索引底层原理
hi ,大家好,今天分享MySQL硬核知识,希望大家可以学习到真正的知识,慢慢积累,厚积薄发: 看完本文可以学到什么 一步一步推导出 Mysql 索引的底层数据结构 怎么分析回答技术选型问题 一步 ...
- Mysql 索引底层原理
一步一步推导出 Mysql 索引的底层数据结构. Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 My ...
- MySQL 索引底层原理详解
大家好 我是积极向上的湘锅锅
- mysql 取第一条_MySQL索引底层(一)索引底层原理
微信公众号:Java患者 专注Java领域技术分享 MySQL索引底层原理 局部性与页 在操作系统中,我们执行一个指令去磁盘取数据,那么他会从磁盘取出4KB数据,这个4KB就是一个局部单位,而这4KB ...
- mysql 字符串 底层_Mysql 的索引底层原理及数据结构详解
Mysql 的索引底层原理 1.什么是索引? 索引是一种排好序的数据结构,mysql目前默认使用的是b+树. 2.为什么使用b+树? 例如表table 数据 id name 1 zs 2 ls 3 s ...
- MySQL索引底层实现原理 MyISAM非聚簇索引 vs. InnoDB聚簇索引
MySQL索引底层实现原理 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的 ...
- 面试官:MySQL索引底层数据结构原理与性能调优,你能回答多少?
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新,可以微信搜索[小奇JAVA面试]第一时间阅 ...
- 【MySQL】InnoDB行格式、数据页结构以及索引底层原理分析
目录 一.MySQL架构图 二.InnoDB数据页结构 2.1 局部性原理 2.2 InnoDB的数据页格式 三.InnoDB的行格式 3.1 Compact行格式 3.1.1 变长字段长度列表 3. ...
最新文章
- 解读网络“攻城狮”的发展---老赵带你铺一段路
- iphone5新尺寸
- 10.24T3 解方程 取模意义下运算+秦九韶算法
- 单片机中灯泡显示miss_单片机实例分享,如何设计八路抢答器
- 输入某年某月某日,判断这一天是这一年的第几天?(使用python语言)
- 关于for循环中的变量int i 如果跳出了这个for循环后,i的值是继续保留还是被释放掉了
- JS之前台参数提交到后台,双引号转义为解决办法
- java日历类add方法_Java日历setFirstDayOfWeek()方法与示例
- android EditText 控件中加入图片(非背景图片)
- 手把手带你阅读Mybatis源码(二)执行篇
- 杨澜给80后女孩子的14个忠告
- MySQL docker yml 3_分享一个mysql的docker-compose.yml
- linux第五单元作业,第五单元《微型计算机系统》教案
- RandomForest随机森林模型训练
- scratch编程体感游戏
- 微信公众号使用:给微信公众号设置头像和微信号的步骤
- linux返回上级目录
- 图片尺寸怎么修改?分享2种方法快速修改图片尺寸大小
- 弹窗代码大全 弹窗广告代码
- 解决小米miui系统调用系统裁剪图片功能camera.action.CROP后崩溃或重新打开app的问题
热门文章
- 【APICloud系列|12】ios真机调试时如何添加新设备的udid?
- mysql 字符集测试_MySQL多字符集备份恢复测试
- 十三水算法php_基于PHP+Redis令牌桶限流
- 怎么把桌面计算机隐藏文件,怎么隐藏桌面文件夹名称?隐藏桌面图标下的文字的详细教程...
- moment 24小时与12小时区别
- JS实现文本中查找并替换字符
- 解决关于 ionic3 启动白屏 控制台错误提示:Uncaught SyntaxError Use of const in strict mode.
- 博客园如何使用MarkDown
- JavaScript实现表单的全选,反选,获取值
- On Comparing Side-Channel Preprocessing Techniques for Attacking RFID Devices