首页 > 数据库 >一文让你对mysql索引底层实现明明白白

一文让你对mysql索引底层实现明明白白

时间:2024-01-16 11:37:20浏览次数:38  
标签:明明白白 主键 索引 IO mysql 数据结构 数据 节点

开篇:

图片是本人随笔画的,有点粗糙,望大家谅解,如有不妥之处,请联系我们,感谢

一、索引到底是什么

.索引是帮助mysql高效获取数据的排好序的数据结构

.索引是存储在文件里的

.数据结构: 二叉树 HASH BTREE

 

 

 

如果没有索引的话,循环一条一条的找,找一次就是一次IO,这样速度就会很慢

我们知道数据库数据都是存在磁盘上的,当我们查找数据时,就会从磁盘上取数据,每取一次就是一次IO,IO是非常耗时的,为了速度快会把数据放到缓存里,然后在缓存里进行操作

 

二、磁盘存取原理

 

 

 

当查找数据的时候,就是磁头循环找此道,就会一直循环查找,一次查找就是一次IO,IO是很耗时的

三、Mysql数据结构详解

就拿上面的7条数据来说,如果没有索引,当我们查找第7条数据时,就会循环7次,如果有百万级别的数据,那么就会查找百万次,显然这样是不行的,就需要数据结构算法来优化,那我们就从二叉树----HASH---BTREE来一一说起

二叉树:

二叉树节点保存的都是单个索引,高度会随着数据增大而增高,但是比一条一条的循环会快

 

 

 

 

 

 

不用二叉树是因为的极端情况下会出现单边增长,这样在数量大的情况下,和一条一条查找没有区别。

红黑树:

红黑树有自平衡性质,不会出现单边增长,它会动态自旋转,在性能上比二叉树又高一点,但是mysql也没有用这种数据结构,因为数据量超大的情况下,数据高度也会一直增大,在最终这个树高度也非常大,解决不了根本问题

 

 

 

HASH:

hash算法一次就会定位到文件指针,速度快,但是还是没有用,如果范围查找的话就没有办法了,如果只是内存中的话,他的时间复杂度是O(1),速度会会很快,但是索引文件也是保存在磁盘上,而且hash是不连续的放在磁盘上的,这样查询起来也很慢,这才是不用hash的最根本原因

 

 

 

B-TREE:

相比上面的数据结构,b-tree增加了横向大小(度Degree),那么在高度上就减小了,查找次数就少了

 

 

 

15,56,77.。。。。是索引,data就是对应的一行数据

那么在横向的度上最大多少合适呢??总不能横向上一直扩展下呀,磁盘一次IO,就是取一个横向的节点(度),把一个节点的数据放在缓存中,那么一次IO也不能把所用的数据全取出来,所以最好是一次io,就把这个节点全取处理,电脑操作系统从磁盘一次取数据到内存中一般是4K,而mysql取一次数据一般是16K,所以横向节点一般设置为16K。因为一个节点设置成16K的话,这个节点保存了索引和索引对应行的数据,那么这个节点横向保存不了太多的数据,所以,这种数据结构也不合适,引入新的数据结构

 

 

 

B+Tree

查找一次数据就是和磁盘一次IO,一次IO会把这个数据相邻的数据一下全部查处理,这样速度会更快,这样的一页就是咱们说的一个节点(4K),分配空间的时候也是一页一页分配的,这样会更快,一页就是一个节点

 

 

 

 

mysql 常用的引擎有MyISAM和InNoDb,两种引擎得索引结构是不一样的

MyISAM的数据结构:

.frm表结构文件 .myd表数据文件 .myi表索引文件

 

 

 

 

 

 

myisam引擎的主键索引数据结构是左上图,普通索引是右上图,叶子节点存的不是数据本身,是数据文件指针,和b_tree数据不一样,注意:每类的索引,都是各自的树,不是混合在一起的

 

.frm表结构文件 .ibd 表数据和索引文件

 

 

 

 

 

 

主键索引是聚集索引,因为叶子节点是所有的数据,就是一行数据,非主键索引叶子节点只包括索引和主键,再用主键找对应数据

非主键索引叶子节点只包括索引和主键,再用主键找对应数据,这样是为了节省空间和数据一致性

 

联合索引:

要满足最左原则

联合索引(col1, col2, col3)也是一棵B+树,其非叶子节点存储的是第一个关键字的索引,而叶子节点存储的则是三个关键字col1、col2、col3三个关键字的数据,且按照col1-col2-col3的顺序进行排序。

 

 

 

 

 

例如:

如果执行的是,SELECT * FROM T WHERE B=‘Tom’ AND C=4567;

那么无法使用索引,因为索引是用A字段先排序的,如果没有先确定A,直接查找B和C,那么将会是全表查询。

 

如果执行的是,SELECT * FROM T WHERE A=‘30’ ;

那么,会先找到A字段,再在A等于30的数据中(比如有很多条),找B等于Demi的数据。这样是可以用到索引的。

 

如果执行的是,SELECT * FROM T WHERE A=‘18’ AND C=1234;

那么,A字段可以索引,而C不能索引。所以可以部分索引,也比全表查询快。

 

如果执行 SELECT * FROM T WHERE B=Demi AND C=1234 and A=‘18’

是用到索引的,在and的情况下如果把第一个放到最后位置也是能用到索引的

 

现在我想大家应该了解了什么为什么是最左原则。因为,B+树是按照最左边的字段以此构建的。

作者:京东零售 韩航云

来源:京东云开发者社区 转载请注明来源

标签:明明白白,主键,索引,IO,mysql,数据结构,数据,节点
From: https://www.cnblogs.com/jingdongkeji/p/17967262

相关文章

  • 一文让你对mysql索引底层实现明明白白
    开篇:图片是本人随笔画的,有点粗糙,望大家谅解,如有不妥之处,请联系我们,感谢。一、索引到底底是什么.索引是帮助mysql高效获取数据的排好序的数据结构.索引是存储在文件里的.数据结构:二叉树HASHBTREE如果没有索引的话,循环一条一条的找,找一次就是一次IO,这样速度就会很慢我们知道数据库......
  • mysql 中 utf8、utf16、utf32、utf8mb3、utf8mb4的区别
    UTF-8-“大小优化”:最适合基于拉丁字符的数据(或ASCII),每个字符只需1个字节,但大小相应增加符号种类(在最坏的情况下,每个字符最多可增加6个字节)UTF-16-“平衡”:每个字符至少需要2个字节,足以支持现有的主流语言集,并且具有固定的大小以便于字符处理(但是大小仍然可变,每个字符最多......
  • 索引失效原因有哪些?
    索引失效通常指的是数据库查询无法有效利用索引,从而导致查询性能下降。1. 模糊查询的前导通配符:当使用模糊查询(如LIKE‘%abc’)时,索引失效,因为通配符在前面会导致索引无法使用。2.  未使用索引字段进行过滤:如果查询条件没有使用到创建的索引字段,数据库可能不会使用该索......
  • MySQL-12.MySQL数据类型
    1.MySQL中的数据类型常见数据类型的属性,如下2.整数类型2.1类型介绍整数类型一共有5种,包括TINYINT,SMALLINT,MEDIUMINT,INT(INTEGER)和BIGINT。它们的区别如下表所示2.2可选属性整数类型的可选属性有三个2.2.1MM:显示宽度,M的取值范围是(0,255)。例如,int(5):当数据宽度小......
  • Mysql常用存储引擎以及区别?
    InnoDB:是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。MyISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作......
  • MySQL常规(总结)
    1.exist和in的区别1.1select*fromA whereidin(selectidfromB)in 先查询子表,再查询主表,不管子查询是否有数据,但是in只执行一次,查出B表中的所有id字段并缓存起来,检查A表的id是否与B表中的id相等,直到遍历完A表所有记录,所以当子查询数据较大时不适合使用in,因为它会将子......
  • 数据库学习笔记(一)—— 初识MySQL
    初识MySQL介绍什么是数据库? 数据库是结构化信息或数据的有序集合,一般以电子形式存储在计算机系统中。通常由数据库管理系统(DBMS) 来控制。在现实中,数据、DBMS及关联应用一起被称为数据库系统,通常简称为数据库。数据库与电子表格有何区别?数据库和电子表格(例如......
  • Qt连接MySQL数据库失败
    连接MySQL数据库时报错:QSqlDatabase:QMYSQLdrivernotloadedQSqlDatabase:availabledrivers:QSQLITEQODBCQODBC3QPSQLQPSQL7有上述报错是因为使用的qt版本不自带mysql的驱动,需要手动编译。可以检查一下D:\pawf\Program\dev\cpp\Qt\5.15.2\mingw81_64\plugins\sqldri......
  • 我成为开源贡献者的原因竟然是做MySql-CDC数据同步
    今年下半年机缘巧合下公司决定搭建自己的数据中台,中台的建设势必少不了数据集成。首先面临的就是数据集成技术选型的问题,按照社区活跃度、数据源适配性、同步效率等要求对市面上几个成熟度较高的开源引擎进行了深度调研。最终经过内部讨论决定用ApacheSeaTunnel作为数据集成的基......
  • mysql8.0用户与权限管理
    1、用户管理1.1、密码过期策略在MySQL中,数据库管理员可以手动设置账号密码过期,也可以建立一个自动密码过期策略。过期策略可以是全局的,也可以为每个账号设置单独的过期策略。ALTERUSERuserPASSWORDEXPIRE;练习:ALTERUSER'kangshifu'@'localhost'PASSWORDEXPIRE;......