后台-系统设置-扩展变量-手机广告位-内容正文顶部 |
文章目录
- 索引
- MySQL
- 认识磁盘
- MySQL与磁盘交互的基本单位
- 建立共识
- 索引的理解
- 单个page
- 多页情况
- 什么是主键索引
- 为什么只能是B树
- 聚簇索引vs非聚簇索引
- 非聚簇索引
- 聚簇索引
索引
索引提高数据库的性能提高数据库的检索速度不用加内存不用改sql不用改程序速度可以提高成败上千倍但是插入更新删除的速度就比较慢
常见的索引
- 主键索引primarykey
- 唯一键索引unique
- 普通索引index
MySQL
MySQL的工作过程
- mysql对数据做的CURD的操作根据冯诺依曼体系mysql是不可能直接去访问磁盘的
- 实际上数据库对数据做的所有访问全部都是在内存中进行的
- 如果数据有变化再定期的把数据刷新到磁盘里面
- sync使用使用这个系统调用把内核数据刷新到磁盘里面不经过OS
- 示例添加索引前
我们插入了大量的数据然后从里面进行查找数据这样我们就会发现了查询的结果会查很久
- 查询员工号2998877
我们发现很慢时间过了很久才能查询出来
- 示例添加索引后
我们在添加索引之后发现查找的非常块几乎每花什么时间 数据存储效率很低路上还要有带宽限制因为我们在传输数据的时候不仅要在自己的磁盘中传送还要在网络中进行跨网络传输 所有的数据都是基于LInux文件系统的 要找到一个文件的全部本质上就是在磁盘中找到所有保存文件的扇区 磁盘里面磁头确认的是哪一个面磁盘确认的是哪个圈扇区来进行确认是哪一块区域来定位到某一个扇区CHS定位方案磁盘使用的方案 结论 如果OS直接用硬件提供的数据大小进行交互那么系统软件 磁盘的交互都是使用4KB进行交互 MySQL作为一款软件可以想象成一个特殊的文件系统它有更高的IO场景为了提高效率 也就是说磁盘这个硬件的基本单位是512字节而MySQL使用16kb进行IO交互即 如果它的基本单位和磁盘一样的话万一磁盘的基本单位变了它也要跟着变兼容性不行 IO请求----系统中一定存在大量的IO请求————操作系统一定也要管理这些IO请求 磁盘中,磁盘中一定是要对这些io请求进行管理的 创建表 我们这里是故意乱序的进行数据的插入 我们中断一下排序的工作是由谁操作的为什么要这样干呢? 每次交互都使用page16KB这样一次可以预加载很多可以充分利用局部性原理。 为何MySQL和磁盘进行IO交互的时候要采用page的方案进行交互用多少加载多少的方式不香吗 如上面的5条数据MySQL要查id2第一次加载id1第二次加载id2一次一条数据就要进行2次IO如果要找id5就需要5次IO 但是如果5条数据都被保存再page里面16kb能保存很多记录第一次IO查找的时候整个page就直接加载MySQL的bufferpool里面了这里完成了一次IO但是往后的id1345等就不需要进行IO了而是直接再内存里面进行了大大减小了IO的次数 你怎么保证用户下次找的数据就再这个page里面我们不能保证但是会由很大的概率因为由局部性原理往往IO效率低下唉最主要矛盾不是单次IO的数据量大小而是IO的次数 正式理解索引结构,一定会存在page结构体 对page的管理就是对链表的管理 之后的操作都是再内存当中实现的 理解多个page 页内目录 用目录查找效率就很高第一章是什么在第几页这样查找就很快以空间换时间 假如说数据500条我们目录10条这样就是只要遍历10次目录遍历50次目录中对应的数据大大减少了遍历的次数 page之间也是线性的怎么提高page之间的搜索效率 page内部的效率问题 page和page之间的效率问题 数据不断的插入新增mysql很容易容量不足所以就需要开辟一个新的page来保存数据然后通过指针的方式来将所有的page组织起来 因为我们要保证一个整体有序所以新来的数据不会放在新的page里面 这样我们就可以通过多个page的遍历page内部用目录进行定位数据可是这样也有效率问题在page里面我们也需要用mysql进行遍历这样就显得我们之前的page有点没用了,我们查找一个数据需要把前面的所有page遍历一遍 解决方案 给我们的一个一个page也带上目录 把每个page里面最小的记录作为每个page的键值这样page和page之间键值就不会重复了 在page之间和page内部都添加目录结构这样就能构建一个b树 在MySQL内部将热点数据以B树的形式将所有的page页进行组织形成的数据结构与其配套的查找算法叫做索引 添加索引就给业内加目录给顶层添加目录结构方便对数据进行筛查 有了b树每次从叶子节点中进行搜索一路找下去就可以查找到对应的数据了 只要我们把页目录加载进去之后这些目录就常驻了以后就不需要再加载到内存了减少了IO的次数 但是其实目录页本来就没多少所以可以直接都加载进来 但是如果插入数据删除数据的时候会影响一下效率因为会影响整个页目录的结构 B树 B树在哪里 同样文件也是内存中一定是被打开的文件 数据和索引分离 myisam的叶子节点不存储数据只存储数据对应的地址这样就能保存更多键值和索引关系把数据放到对应的一个地方用指针进行索引 把索引page和数据page进行分离也就是叶子节点没有数据只有对应数据的地址 innodb就是聚簇索引 辅助索引 MySQL除了会建立主键索引之外还会建立按照其他列信息建立索引一般这叫做辅助索引其他字段也能建立索引 主键就是叶子有地址有索引 附上数据太浪费空间了会造成数据的冗余但是myisam不需要进行回表查询效率还是回更高一点但是innodb支持事务而mysiam不保证事务 下一次访问的数据有很大概率会和上一次访问的数据重叠↩︎
我们会发现搜索的时间不到一秒认识磁盘
磁盘的使用使用的LBA逻辑块地址可以理解为虚拟地址和物理地址这个是操作系统使用的方案
我们已经能够在硬件层面上定位到对应的地址了任何一个数据块扇区在系统软件上直接按照扇区512字节会造成过度寻址所以我们基本都是使用4096来进行寻址4页
连续磁盘访问MySQL与磁盘交互的基本单位
MySQL和磁盘进行数据交互通过OS的基本单位是16KB这个基本数据单位在mysql里面叫做page
所以这里规定MySQL数据交互的基本单位是16KB1page建立共识
先描述再组织索引的理解
我们select之后发现查询的结果是按照主键顺序进行排序的
为何IO交互要使用page?单个page
mysql插入数据时按照主键来进行排序插入后page里面就是有序的,查找的时候就能优化查找算法有序的就可以提高查找效率如二分查找方便我们进行查找
先在一个page里面提高搜索效率那么在所有page里面效率也提高了很多
有了目录就能一次淘汰很多数据这样就会导致单页中数据减少我们是先遍历数据目录再去便利数据记录这样提高的效率就很大我们先遍历目录多页情况
问题
在page里面中在开一个page里面就只保存下面所管理的主键和指针只保存一个一个目录
用一个page专门来保存page目录和page对应的地址一个page可以管理2000多个page
直接到顶层的page目录
数据量很大的话还要继续在中间增加page目录
相当于一个b树一个节点可以索引到很多地址至此我们就已经可以给我们的表user构建完主键索引了
随便找一个id我们发现现在查找的page树一定减少了说明我们IO次数也减少了那么效率也高了什么是主键索引
如果没有添加索引所有的数据都是以链表的形式串联起来数据没有做优化没有排序插入什么样就是什么样的
现在我们就不用加载很多数据到内存中不需要查找的page就不需要加载到内存中了我们需要哪个page加载哪个page即可一路把我们查询过程中的路径page加载进去即可
修改了一个数据都要以整个page进行刷新到磁盘中为什么只能是B树
创建了一个索引它就会创建一个文件叫.ibdindex_block_data,这个说明数据和索引合在一起的
把索引和数据都加载进去了聚簇索引vs非聚簇索引
非聚簇索引
聚簇索引
把数据和索引聚合在一起
和主键索引没有差别无非是主键不能重复而非主键可以重复
同样是构建b树innodb非主键索引中叶子节点保存对应地址的索引但是没有保存数据太浪费空间了包含的是对应主键再根据主键进行查询索引回调索引两边索引先获得主键再主键索引获得索引的记录
后台-系统设置-扩展变量-手机广告位-内容正文底部 |
您可以选择一种方式赞助本站
支付宝转账赞助
支付宝转账赞助