MySQL存储引擎及索引机制

news2024/9/21 19:05:22

MySQL技术——存储引擎和索引机制

    • 一、存储引擎概述
    • 二、常见存储引擎的区别
    • 三、索引机制
    • 四、索引的底层实现原理
    • 五、InnoDB主键和二级索引
    • 六、聚集索引和非聚集索引
    • 七、哈希索引
    • 八、InnoDB的自适应哈希索引
    • 九、索引常见问题
    • 十、慢查询日志
    • 总结

一、存储引擎概述

插件式存储引擎是MySQL数据库最重要的特性之一,用户可以根据应用的需要选择如何存储和索引数据、是否使用事务等。MySQL默认可以支持多种引擎,适用于不同领域的数据库用于需要,常见的MySQL存储引擎有:InnoDBMyISAMMemoryNDB Cluster等等,在mysql 的命令行窗口中,我们可以通过命令show engines查看
在这里插入图片描述

二、常见存储引擎的区别

  • InnoDB存储引擎:具有提交、回滚和崩溃恢复能力的事务安全,支持自动增长列,外键等功能,采用聚集索引,即索引和数据存储在同一个文件,文件名和表名相同,扩展名分别为:.frm(存储表的定义)、.idb(存储数据和索引)
  • MyISAM存储引擎:不支持事务、也不支持外键,索引采用非聚集索引,优势为访问速度快,对事务完整性没有要求,以select、insert为主的可以使用这个引擎来创建表,它在磁盘上存储成3个文件,扩展名为:.frm(表定义)、.MYD(数据)、.MYI(索引)
  • MEMORY存储引擎:使用存在内存中的内容来创建表,每个表对应一个磁盘文件,由于它的数据是放在内存中的,因此该类型的表访问非常快,并且默认使用hash索引(不适合于范围查询),但是一旦服务关闭,表中的数据就会丢失
存储引擎锁机制B-树索引哈希索引外键事务索引缓存数据缓存
InnoDB行锁支持不支持支持支持支持支持
MyISAM表锁支持不支持支持不支持支持不支持
Memory表锁支持支持不支持不支持支持支持

锁机制:数据库在并发请求访问的时候,多个事务在操作时,并发操作的粒度

B-树索引和哈希索引:加速SQL的查询速度

外键:子表的字段依赖父表的主键,设置两张表的依赖关系

事务:多个SQL语句,保证它们共同执行的原子操作

索引缓存和数据缓存:与MysSQL Server的查询缓存相关,在没有对数据和索引进行修改前,重复查询可以不进行磁盘I/O,直接上一次内存中查询的缓存

三、索引机制

当表中的数据量达到了几十万甚至上百万时,SQL查询所花费的时间会很长,有时会导致业务出现超时出错,这时我们需要使用索引来加速SQL的查询速度。但索引本身也是需要存储成索引文件1的,因此对索引的使用也会涉及到磁盘I/O操作,如果索引创建过多或使用不当,仍然会造成SQL查询时的大量的无用的磁盘I/O操作,降低查询效率,因此我们需要理解清楚索引创建的原则

  • 索引的优点:提高查询效率

  • 索引的缺点:过多的索引会导致CPU使用了居高不下,数据的改变造成索引文件的改动,过多的磁盘I/O造成CPU负荷太重

  • 索引的分类:

    • 普通索引:没有任何限制条件,可以给任何类型的字段创建普通索引,数量不限
    • 唯一性索引:使用unique修饰的字段,值不能重复,主键索引就隶属于唯一性索引
    • 主键索引:使用primary key修饰的字段会自动创建索引
    • 单列索引:在一个字段上创建索引
    • 多列索引:在表的多个字段上创建索引
    • 全文索引:使用FULLTEXT参数可以设置全文索引,只支持CHAR、VARCHAR、TEXT类型的字段,常用于数据量较大的字符串类型上,可以提高查询速度(如elasticsearch,简称es C++开源的搜索引擎 workflow)
  • 使用索引的原则:

    1. 一般情况,一次查询只能使用一条索引
    2. 对查询where条件中区分度高的字段加索引
    3. 联合索引,叶子节点存储的顺序以创建时指定的顺序为准,因此区分度高的放左边,能被多个查询复用的放左边
    4. 只select需要用到的字段,尽量避免使用select*
    5. 如有必要,可以使用force index强制索引,select * from xxx force index(ix_addtime);
    6. 多表join,按各表的查询条件比较哪个表开销小,从小表取出符合条件的,到大表循环查找
    7. 以下情况无法使用到索引:
      • like通配符在最左 ‘%xxx%’,not in,!=,<> 涉及到类型强转,mysql函数调用、表达式计算等等

查看表的索引:有一个主键索引
在这里插入图片描述

索引的创建和删除

//创建时指定的索引字段
create table user(
	id int primary key,
	name varchar(50),
	age int,
	index(name, age);  //这是多列索引
);

//在已经创建的表上添加索引
create index name_idx on user(name);

//删除索引
drop index name_idx on user;

这是添加了name_idx的结果
在这里插入图片描述
查找指定的 id = 10000
在这里插入图片描述
查找指定的 name = ‘Test_50000’
在这里插入图片描述
删除name_idx索引,再查找指定的 name = ‘Test_50000’
在这里插入图片描述

通过上述的查询操作,效果可见一斑,现在给出explain结果字段分析

  • select_type

    • simple:表示不需要union操作或者不包含子查询的简单select语句。有连接查询时,外层的查询为simple且只有一个。
    • primary:一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary且只有一个。
    • union:union连接的两个select查询,除了第一个表外,第二个以后的表的select_type都是union。
    • union result:包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null。
  • table

    • 显示查询的表名;
    • 如果不涉及对数据库操作,这里显示null;
    • 如果显示为尖括号就表示这是个临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生的;
    • 如果是尖括号括起来<union M,N>也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集;
  • type

    • const:使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type就是const。
    • ref:常见于辅助索引的等值查找,或者多列主键、唯一索引中,使用第一个列之外的列作为等值查找会出现;返回数据不唯一的等值查找也会出现。
    • range:索引范围扫描,常见于使用<、>、is null、between、in、like等运算符的查询中。
    • index:索引全表扫描,把索引从头到尾扫一遍;常见于使用索引列就可以处理不需要读取数据文件的查询,可以使用索引排序或者分组的查询。
    • all:全表扫描数据文件,然后在server层进行过滤返回符合要求的记录。
  • ref

    • 如果使用常数等值查询,这里显示const;
    • 如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段;
  • Extra

    • using filesort:排序时无法用到索引,常见于order by和group by语句中。
    • using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。

四、索引的底层实现原理

索引搜索的具体过程 !!!

当SELECT涉及到索引时,数据库系统会优先从内存中的索引缓存中查找匹配的数据行。如果索引缓存中不存在需要的索引,数据库系统会通过磁盘IO操作,从磁盘中读取索引页,找到匹配的数据行,然后将其加载到内存中加速查询数据的执行

MySQL能够支持两种索引:B-树索引、哈希索引(但实际上MySQL采用的是B+树结构)

B树索引

B树索引是一种特殊的B树,它被设计用于在磁盘上存储数据。因为磁盘的访问速度相对较慢,所以B树索引被优化为减少磁盘访问次数。它可以将大量的数据分层存储在不同的节点中,使得查询的时候只需要少量的磁盘读取操作。由于磁盘的读取也是按block块操作的(内存是按page页面操作的),因此B-树的节点大小一般设置为和磁盘块大小一致,这样一个B-树节点,就可以通过一次磁盘I/O把一个磁盘块的数据全部存储下来,所以当使用B-树存储索引的时候,磁盘I/O的操作次数是最少的

B树索引的原理如下:

  • 每个节点可以包含多个key-value对,其中key是索引列的值,value是对应的数据行的指针或位置(下图B-树是基于InnoDB存储引擎的,索引树上放的就是数据,所以data存储的直接就是数据本身的内容;而如果是MyISAM存储引擎,由于存放索引和数据的是两个不同的文件,其data存储的是在磁盘上包含的对应索引值记录的地址)

  • 所有的节点都按照key的大小有序存储,也就是说,节点中的key是递增的

  • 每个节点中的key可以重复,这样可以处理重复值的情况

  • 每个节点中可以有多个子节点,子节点的key的范围必须满足一定的条件,使得它们可以作为查询的条件进行过滤

  • 每一个叶子节点都包含一个指向数据行的指针或位置,这样可以直接找到需要的数据

在这里插入图片描述
从上图可以看到B-树存在的缺点:

  • 每个节点中有key,也有data,但是每一个节点的存储空间是有限的,如果data数据较大时会导致
  • 每个节点能存储的key的数据很小
    当存储的数据量很大时同样会导致B-树的高度较大,磁盘IO次数花费增大,效率降低

在这里插入图片描述
虽然B-树有很多优点,但在MySQL里,却是采用B+树存储索引结构的🤔🤔🤔

  1. B-树的每一个节点,存了关键字和对应的数据地址,而B+树的非叶子节点只存关键字,不存数据地址。因此B+树的每一个非叶子节点的关键字是远远多余B-树的,从树的高度上看,B+树的高度要小于B-树,使用的磁盘IO少,查询更快
  2. B-树由于每个节点都存储关键字和数据,因此离根节点近的数据,查询就快,离根节点远的数据,查询就慢;而B+树的所有数据都存在叶子节点上,在它上面搜索关键字,找到对应数据的时间是比较平均的,没有快慢之分
  3. 对于区间查找,在B-树上的遍历节点非常多;而B+树的所有叶子节点被连接成了有序链表结构,做整表遍历和区间查找非常容易

五、InnoDB主键和二级索引

user表中 id为主键 这里默认InnoDB

1、explain select * from user where id = 1; 做等值查询 type: const在这里插入图片描述
2、explain select * from user where id < 5;做范围查询 type: range
在这里插入图片描述
3、explain select * from user where name = 'Test_10000';做整表搜索
在这里插入图片描述
user表中 id为主键,name创建了普通索引(二级索引)
1、explain select name from user where name = 'Test_10000' 使用辅助索引 type: ref
在这里插入图片描述
2、explain select id, name from user where name = 'Test_10000'; 使用辅助索引 type: ref
在这里插入图片描述
3、explain select * from user where name = 'Test_10000'; 这里涉及到了回表操作

  • 先搜索name的二级索引树,找到 'Test_10000’对应的主键id:10000
  • 再那id = 10000回表,在主键索引树上搜索id对应的那一行记录

在这里插入图片描述

这里进行一次查询:select * from user where age = 20 order by name,只给age添加索引,行不行?(不行)
在这里插入图片描述
Extra:using filesort 排序时无法用到索引,常见于order by、group by中
因此我们需要使用多列索引(联合索引)优化,先按age排序,再按name排序;age相同,则按name排序
在这里插入图片描述

下面给张图辅助理解
在这里插入图片描述
对于MyISAM存储引擎则是这样的
在这里插入图片描述

六、聚集索引和非聚集索引

  • MyISAM存储引擎,索引结构叶子节点存储关键字和数据地址,也就是说索引关键字和数据没有在一起存放,体现在磁盘上,就是索引在一个文件存储,数据在另一个文件存储,例如一个user表,会在磁盘上存储三个文件 user.frm(表结构文件)user.MYD(表的数据文件) user.MYI(表的索引文件)。MyISAM的索引方式也叫做非聚集索引。
    在这里插入图片描述
    在这里插入图片描述

  • InnoDB的索引树叶节点包含了完整的数据记录,这种索引叫做聚集索引。 因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(区别于MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
    在这里插入图片描述
    在这里插入图片描述

七、哈希索引

>    B+树索引 O(logn) : 搜索效率好、磁盘IO少
>    哈希索引 O(1): 基于Memory存储引擎
create index name_idx on user(name) using hash / btree; 创建哈希索引,InnoDB不支持

show create table user\G;  //不准确

show indexes from user;  //真实
  • 哈希表中的元素没有任何顺序,只适合等值比较,—select * from suer where name = 'Test_1';,对于like ‘xx%’,范围查询,前缀搜索,order by排序等等都不行
  • 没办法处理磁盘上的数据,加载到内存上构建高效的搜索数据结构,因为它没法减少磁盘IO次数
  • 只适合基于内存上的搜索

八、InnoDB的自适应哈希索引

当InnoDB存储引擎检测到有同样的二级索引不断被使用,那么它会对这个二级索引,在内存上根据二级索引树(B+树)上的二级索引值来创建一个哈希索引,加速搜索

在这里插入图片描述

#查看自适应是否开启
show variables like 'innodb_adaptive_hash_index';

#查看分区个数
show variables like 'innodb_adaptive_hash_index_parts';

#查看自适应哈希索引的使用情况
show engine innodb status\G;

在这里插入图片描述

注意:自适应哈希索引本身也是需要耗费性能的,不一定会在任何情况下都能够提升二级索引的查询性能,需要根据参数指标,具体分析是否需要打开或者关闭,比如,当RW-latch等待的线程数量过多,同一个分区等待的线程过多, then it might be useful to disable adaptive hash indexing. /

九、索引常见问题

1、为什么有时我们给指定字段添加了索引,但是在搜索的时候,仍然是做的整表搜索?

  • 因为该字段在表中的内容区分度不大,用索引搜索和直接整表搜索差别不大,索引搜索还需要加载磁盘文件,因此mysql会直接做整表搜索

2、查询条件有多个字段,也涉及不同的表JOIN,有些字段建立了索引,会使用哪一个?

  • 由于每次查询只能用到一个索引,mysql会优先找小表的(在where条件过滤后,表行少的),即小表决定循环的次数,大表决定每次循环的时间

3、.............

十、慢查询日志

虽然我们可以通过explain分析select语句来进行sql语句查询的性能,但是对于一个项目而言,可能包括了很多业务操作,其中mysql语句也是不计其数,这是我们可以依靠 慢查询日志,找出指定的运行时间长、耗性能的sql,进行分析优化

主要步骤:

  • 开启慢查询日志,设置合理的慢查询时间
  • 压测执行各种业务
  • 查看慢查询日志,找出所有执行耗时的sql
  • 用explain分析耗时的sql
  • 举例…

show variable like 'slow_query_log%'
在这里插入图片描述
set global slow_query_log=on/off
在这里插入图片描述
show variables like 'long_query_time%'
在这里插入图片描述
set long_query_time=0.1 100ms,只对当前的section起作用,global对全局
在这里插入图片描述


这里我们进行一次耗时的查询 select * from user where name = 'Test_1000000';
在这里插入图片描述
进入root用户,在 /var/lib/mysql/ 下查慢查询日志
在这里插入图片描述
在这里插入图片描述
由此,我们可以对它做 explain分析
在这里插入图片描述


有些查询时间不是很长,若需要了解它,可以

  • show variable like 'profiling';
  • set profiling=on;
  • show profiles;
    在这里插入图片描述

总结

。。。


🌻🌻🌻以上就是有关于MySQL存储引擎及索引机制的内容,如果聪明的你浏览到这篇文章并觉得文章内容对你有帮助,请不吝动动手指,给博主一个小小的赞和收藏 🌻🌻🌻


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

b站小土堆pytorch学习记录——P7-P8 Tensorboard的使用

文章目录 一、前置知识1.Tensorboard是什么2.SummaryWriter3.add_scalar()4.add_image() 二、代码1.一次函数2.蚂蚁和蜜蜂图片 一、前置知识 1.Tensorboard是什么 TensorBoard 是 TensorFlow 的可视化工具&#xff0c;它允许开发者可视化模型的图&#xff08;graph&#xff0…

一线互联网大厂中高级Android面试真题收录,记一次字节跳动Android社招面试

在开始回答前&#xff0c;先简单概括性地说说Linux现有的所有进程间IPC方式&#xff1a; 1. **管道&#xff1a;**在创建时分配一个page大小的内存&#xff0c;缓存区大小比较有限&#xff1b; 2. 消息队列&#xff1a;信息复制两次&#xff0c;额外的CPU消耗&#xff1b;不合…

驱动高级--mknod

一、起源 仅devfs&#xff0c;导致开发不方便以及一些功能难以支持&#xff1a; 热插拔 不支持一些针对所有设备的统一操作&#xff08;如电源管理&#xff09; 不能自动mknod 用户查看不了设备信息 设备信息硬编码&#xff0c;导致驱动代码通用性差&#xff0c;即没有分离…

【Python】成功解决ValueError: not enough values to unpack (expected 2, got 1)

【Python】成功解决ValueError: not enough values to unpack (expected 2, got 1) &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&am…

本科毕业设计:计及并网依赖性的分布式能源系统优化研究。(C语言实现)(内包含NSGA II优化算法)(二)

目录 前言 1、sofc函数 2、光伏板函数 3、集热场函数 4、sofc电跟随策略函数 5、二分法找sofc运行点函数 6、目标函数&#xff1a;成本 7、目标函数&#xff1a;二氧化碳排放量 8、目标函数&#xff1a;并网依赖性 前言 本篇文章介绍的是我的毕业设计&#xff0c;我将C…

【前端素材】推荐优质后台管理系统Annex平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的管理界面&#xff0c;通常由管理员和工作人员使用。它提供了访问和控制网站或应用程序后台功能的工具和界面&#xff0c;使其能够管理用户、内容、数据和其他各种功能。 2、功能需求 后台管理系…

基于java+springboot动物检疫信息管理系统设计和实现

基于java SSM springboot动物检疫信息管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文…

3d模型版本转换器注意事项---模大狮模型网

在使用3D模型版本转换器时&#xff0c;有一些注意事项可以帮助您顺利完成模型转换并避免不必要的问题&#xff1a; 数据完整性&#xff1a;在进行模型转换之前&#xff0c;确保您的原始3D模型文件没有损坏或缺失数据。损坏的文件可能导致转换器无法正常处理或输出错误的结果。 …

公钥密码体制

公钥密码体制 一个系统中,n个用户之间要进行保密通信,为了确保安全性,两两用户之间的密钥不能一样。这种方式下,需要系统提供C2 n=n(n-1)/2把共享密钥。这样密钥的数量就大幅增加了,随之而来的产生、存储、分配、管理密钥的成本也大幅增加。而使用公钥密码体制可以大大减…

[unity] c# 扩展知识点其一 【个人复习笔记/有不足之处欢迎斧正/侵删】

.NET 微软的.Net既不是编程语言也不是框架,是类似于互联网时代、次时代、21世纪、信息时代之类的宣传口号,是一整套技术体系的统称&#xff0c;或者说是微软提供的技术平台的代号. 1.跨语言 只要是面向.NET平台的编程语言(C#、VB、 C、 F#等等)&#xff0c;用其中一种语言编写…

基于JavaWeb实现的药店管理系统

一、系统架构 前端&#xff1a;jsp | layui | jquery | css 后端&#xff1a;spring | springmvn | mybatis 环境&#xff1a;jdk1.8 | mysql 二、代码及数据库 三、功能介绍 01. 登录 02. 首页 03. 药品管理 04. 销售管理-销售记录管理 05. 销售管理-退…

Day07:基础入门-抓包技术全局协议封包监听网卡模式APP小程序PC应用

目录 非HTTP/HTTPS协议抓包工具 WireShark 科来网络分析系统 WPE封包 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令&#xff1a;文件上传下载/端口服务/Sh…

【YOLO v5 v7 v8 小目标改进】BiFormer:从局部空间特征到高效的全局空间特征

BiFormer&#xff1a;从局部空间特征到高效的全局空间特征 提出背景BiFormer 结构 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 提出背景 论文&#xff1a;https://arxiv.org/pdf/2303.08810.pdf 代码&#xff1a;https://github.com/rayleizhu/BiFormer 问题: 传统的卷…

c++面试三 -- 智能指针--7000字

一、智能指针 C 中的智能指针是一种用于管理动态分配的内存的对象&#xff0c;它们可以自动进行内存管理&#xff0c;避免内存泄漏和悬挂指针等问题。 1. 悬挂指针 悬挂指针&#xff08;dangling pointer&#xff09;是指在程序中仍然存在但已经不再指向有效内存地址的指针。悬…

Android Shadow插件化框架分析与集成(一)

一、shadow源码导入及分析 1、下载项目源码 2、导入到Android studio 3、设置jdk及sdk版本 包/应用描述类型sample-constant公共字符串常量libsample-host宿主应用applicationsample-host-lib宿主应用依赖包libsample-manager是插件管理器的动态实现,主要负责加载插件和安装…

吸引用户购买产品的文案技巧,媒介盒子揭秘

在营销过程中&#xff0c;想要吸引用户购买产品&#xff0c;文案是重中之重&#xff0c;需要一定的技巧才能将文案写好&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;在品牌推广中如何通过一些小技巧吸引用户购买产品&#xff1a; 一、 少说专业术语 少说行话、黑话。多…

【VTKExamples::PolyData】第四十一期 PointLocator

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例PointLocator,并解析接口vtkPointLocator,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. PointLocator …

C++ 补充之常用排序算法

C 补充之常用排序算法 常用的排序算法主要包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序&#xff0c;下面简单介绍一下它们的概念和原理&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a; 冒泡排序是一种基础的排序算法&#xff0c;它重…

【激光SLAM】基于已知位姿的构图算法 (Grid-based)

文章目录 地图分类概念 覆盖栅格建图算法栅格地图的特征数学描述假设 算法流程激光雷达的逆观测模型 计数(Count Model)建图算法概念数学描述观测模型地图估计 地图分类 概念 地图即为环境的空间模型。环境地图是机器人进行定位和规划的前提。定位可以用特征地图&#xff08;…

LNMP架构介绍及配置--部署Discuz社区论坛与wordpress博客

一、LNMP架构定义 1、LNMP定义 LNMP&#xff08;Linux Nginx Mysql Php&#xff09;是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1b;Linux系统下NginxMySQLPHP这种网站服务器架构。 Linux是一类Unix计算机操作系统的统称&#xff0c;是目…