微信公众号:Java患者
专注Java领域技术分享

MySQL索引底层原理

局部性与页

在操作系统中,我们执行一个指令去磁盘取数据,那么他会从磁盘取出4KB数据,这个4KB就是一个局部单位,而这4KB数据就是你的指令中取出的数据周围的数据,因为操作系统认为你下一次的数据会从这条数据的周围中取。每次从磁盘读取数据在这里称为一次磁盘IO。那么在Mysql的操作当中,也有这么一个原理。

数据结构

现在我们有以上数据,当我们执行一句查询语句

select * from t_user where a = 3;

如果mysql没有局部性的概念的时候,那么这条sql会产生三次IO磁盘操作,则mysql会从磁盘取出第一条数据到内存中,然后比对a字段的值,一直比对到第三条才是正确的,那么会产生3次IO磁盘操作,有了局部性后,那么mysql会从磁盘中进行局部性的取出一页数据,这里一页数据是16KB,一次取出来后放到内存中,进行比对,那么就提高了执行效率。

页大小
show global status like 'Innodb_page_size';

通过上面的sql我们知道此时使用的Innodb存储引擎所对应的页大小是16384  也就是16384/1024 = 16KB。

页数据原理

当我们使用insert插入上面的语句的时候,其实可以看到插入的过程中,这4条数据已经按主键的顺序插入到MySQL中,那么在这个插入的过程是怎么样的,我们来研究一下InnoDB存储的过程。

首先插入第一条数据

接着我们插入第二条数据的时候,第二条数据的主键会跟第一条数据的主键比较大小,然后再插入。

最后插入的数据就会根据主键的大小来排序了

插入的数据就形成了我们页数据中的一部分--用户数据区域,并且每一条数据都有一个指针指向了下一条记录,这也形成了一个链表的形式,现在比如说我们要找a=3的数据,那么我们就得从第一条比对到第三条数据,然后取出,那如果有10000条数据呢?需要比对10000次。因为这是一个链表的数据结构,我们都知道链表的数据结构是增删快,查找慢,那么MySQL的InnoDB的存储引擎是怎么解决的呢,在这里引入了一个页目录

页目录在这里重新为主键排了一次序,比如一组的数据是2条,那么主键为1跟主键为2就为一组

如图,如果当我们要查找a=4的这一条数据,那么就从页目录中找,就可以立即找到该条数据会在第二组,然后在第二组中比对到了a=4之后,取出数据。这就是一页数据,那么当数据足够多,多到一页已经放不下了,自然就会有第二页。这里就引出一个页的指针。

接下来的页就会变成上面的数据结构,假设我们现在要找a=6的数据,那么就会基于第一页去找,发现第一页没有,那就基于第一页到第二页去找,发现在页目录5中,那么a=6就在页目录为5的组中取出数据,假如当页数达到了10000页呢,我们要找a=20000的数据,那就得一页一页的去比如页目录中的值,数据太多也很麻烦,现在就会有一个目录页的数据结构出来,也是同样的思路。

当我们要查找a=6的数据,在目录页中可以定位到在第100页的地址,那么我们就可以直接在第100页中去查找我们的数据。

最后渐渐的,就变成了一个B+树的数据结构。

mysql 取第一条_MySQL索引底层(一)索引底层原理相关推荐

  1. mysql 同一天多条记录只取第一条_MySQL面试高频100问(二)

    点击上方蓝字关注我们 表结构设计 1. 为什么要尽量设定一个主键? 主键是数据库确保数据行在整张表唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的ID列作为主键.设定了主键之后,在后续的 ...

  2. mysql分组排序取第一条记录

    方式1:内层使用DISTINCT SELECTtype,senderName,subTitle FROM(SELECT DISTINCTTYPE AS type,SENDER_USERNAME AS ...

  3. Oracle根据行号达到分组排序取第一条的效果,排序后取第一条

    Oracle数据无法根据单个字段进行分组,而mysql可以,如果想要达到根据单个字段进行分组可以查询他的行号获取rowNumber达到单个字段分组取第一条效果 SELECT * FROM (SELEC ...

  4. oracle排序后第一条,Oracle排序取第一条数据

    Oracle需要更新套组的大单位, 规则是取第一个学员(套组ID最小)的单位信息. Oracle需要更新套组的大单位, 规则是取第一个学员(套组ID最小)的单位信息. 采用按照SUITEID排序取第一 ...

  5. 【ES】分组后每组取第一条

    表格如下: 想要获得所有测站最新的一条数据,即先对Station分组,根据time进行排序(降序),取第一条. GET test/_search {"query":{"b ...

  6. 【基础】ARM芯片上电取第一条指令流程

    转载:ARM上电启动及Uboot代码分析 网上关于ARM的bootloader(以Uboot为例)的启动顺序的资料有好多,但是对于Uboot的地址映射.体系结构级操作介绍很少,都是直接开始Start. ...

  7. MySQL查询第一条记录和最后一条记录

    提示:阅读此博客预计消耗你5-8分钟 我们在进行项目需求开发的时候,可能会遇到查询满足特定条件的记录,但是如果有多条记录都满足条件,该怎么弄? 下面提供两条案例,具体使用可按照自己需求进行更改. 1. ...

  8. Oracle中实现分组后按时间排序取第一条

    一.实现效果 ①原表效果:存在重复的编号(PARTNER_ID)内容,访问时间(VISIT_DATE)不同 ②分组排序后取第一条的效果:[实现对编号去重,且取访问时间最新的一条数据] 二.sql语句 ...

  9. oracle分组查询取第一条

    在 Oracle 中,可以使用 row_number() 函数来实现分组取第一条记录的功能.例如,假设有一张表 mytable,其中有两列 col1 和 col2,并且想要按照 col1 分组,并取出 ...

最新文章

  1. 擦除:提升 CNN 特征可视化的 3 种重要手段
  2. css loader.net,* !!vue-style-loader!css-loader?
  3. 黄聪:自动化测试的7个步骤
  4. [MySQL实践] 实践记录
  5. VTK:可视化之ColorSeriesPatches
  6. ConditionObject源码
  7. 递归和迭代路由_静态路由在以太网接口中的不同书写会导致路由器怎样的操作结果?...
  8. NVLink技术及影响解析
  9. sql 同一字段合并
  10. Android中文翻译组 - 简介
  11. .net下完成端口(IOCP)的实现
  12. ES6 class关键字 ~ 非常详细
  13. 【数据结构和算法笔记】:图的深度优先搜索(DFS)
  14. PAT1018 Public Bike Management【dfs】【最短路】
  15. NoSQL数据库简介——《大数据技术原理与应用》课程学习总结
  16. SLAM学习 | 使用小觅相机MYNTEYE-S1030收集数据集
  17. NYOJ234吃土豆
  18. 基于宝塔面板把网站和数据库文件备份到又拍云存储空间图文教程
  19. 如何在水晶报表里显示图象?
  20. IoT企业物联网平台,从设备端到云端业务系统全链路开发实战——实践类

热门文章

  1. [LeetCode] Power of Four
  2. JS中浮点数运算误差处理
  3. Part1: Specification of Required Functions
  4. 中国大学MOOC“Python程序设计基础”第6次开课时间
  5. 微课|中学生可以这样学Python(例6.4):因数分解
  6. Python面向对象程序设计中属性的作用与用法
  7. C语言 如何计算结构体的大小
  8. C语言 模拟实现 strlen strcat strcpy函数
  9. JavaWeb中filter的详解及应用案例
  10. java在未来_如何在java中创建一个完整的未来