【MySQL】如何理解索引(高频面试点)
一、前言
首先这个博客会介绍一些关于MySQL中索引的基本内容以及一些基本的语法,当然里面也会有些常见的面试题的解答。
二、关于索引
1、概念
索引是一种能够帮助MySQL高效的去磁盘检索数据的一种数据结构。在MySQL的Innodb存储引擎中呢,采用的是B+树的结构去实现索引和数据的存储。
2、原理
未添加索引:
如图所示:当我们未添加索引时,假如以id查询某个学生信息时,我们的MySQL会做一个全表的扫描查询,不管你查询的是id=1还是id=5。所以当数据量增多时,我们的查询时间就会增多。
假设现在我们以id建立索引:
如图所示,当我们建立以id为索引时,MySQL在查询的时候,我们的id索引会形成二叉树的结构(该二叉树的前提是平衡二叉树,当然还有B树、B+树的数据结构),如这时我们要查找id=3的学生,MySQL就从id=2开始,3>2,走右子树,找到4,4>3,走左子树找到3。这时查找速度远快于没有索引时的结构。
三、常见索引的种类
1、主键索引(Primary key)
只要我们创建了主键(primary key),那么它就主动成了一个索引,称为主键索引。
2、唯一索引(Unique)
在我们的表的字段中,我们创建了唯一约束(unique),那么该字段是唯一的,同时也是索引,称为唯一索引。
3、普通索引(Index)
普通索引是最基本的索引,它没有任何限制。这也是我们用的最多的索引机制。
4、全文索引(Fulltext)
全文索引适用于MyISAM存储引擎。
四、常见的索引的指令
①查询索引
show indexs from 表名;
②添加索引:
普通索引:
(1)alter table 表名 add index 索引名称(列名);
(2)create index 索引名称 on 表名(列名);
唯一索引:
create unique index 索引名称 on 表名(列名);
主键索引:
alter table 表名 add primary key 列名;
③删除索引:
drop index 索引名称 on 表名
删除主键索引
alter table 表名 drop primary key
④查询索引
(1)show index from 表名;
(2)show inedexs from 表名;
(3)show keys from 表名;
(4)desc 表名。
五、适合索引的情况
①:比较频繁的作为查询条件的字段应该创建索引;
②:唯一性太差的字段不合适 单独作为索引,即使频繁的作为查询条件(如人的性别,有男、女两种状态唯一性差);
③:更新非常频繁的字段不适合创建索引;
④:不会出现在where(或者having)子句中的字段不应创建索引。
六、市面上高频常见的索引的面试回答
这里呢是博主找了一些市面上常见的有关索引的面试题,做个总结,以便于后期的复习。
1、谈谈MySQL索引的优缺点
优点:
①通过B+树的结构来存储数据,可以大大减少数据检索时的磁盘IO的次数,从而提升数据查询的性能;
②B+树索引在进行范围查找的时候,只需要找到起始节点,然后基于叶子节点的链表结构往下读取即可,查询效率较高;
③通过唯一索引的约束,可以保证数据表中每一行数据的唯一性;
缺点:
①数据的增加、修改、删除,需要涉及到索引的维护,当数量较大的情况下,索引的维护会带来较大的性能开销;
②一个表中允许存在一个聚簇索引和多个非聚簇索引,但是索引数不能创建多个,否则会造成索引维护成本过高;
③创建索引的时候,需要考虑到索引字段值的分散性,如果字段的重复数据过多,创建索引反而会带来性能的降低。
2、聚簇索引与非聚簇索引区别
(MySQL的索引从物理存储的角度对索引进行分类可以分为聚簇索引(Innodb)与非聚簇索引(MyISAM))
聚簇索引:所谓聚簇索引,就是指主索引文件和数据文件为同一份文件,聚簇索引主要用在Innodb存储引擎中。在该索引实现方式中B+Tree的叶子节点上的data就是数据本身。因此从聚簇索引中获得数据要比在非聚簇索引中查找更快。
首先我们可以看到我们的Innodb存储引擎中有以下两个文件:
其中.frm文件表示表的结构,.ibd文件表示Innodb 数据表索引+数据,它是索引与数据在同一个文件中,是聚合在一起的。
其次聚集索引的结构如下,我们可以清晰看到数据和索引存储在同一个文件之中的。
非聚簇索引: 非聚簇索引就是指B+Tree的叶子节点上的data,并不是数据本身,而是保存的实际指向存放数据块的指针。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,主要用在MyISAM存储引擎中。 非聚簇索引需要先查询一遍索引文件,得到索引,根据索引获取数据,比聚簇索引多了一次读取数据的IO操作,所以查找性能上会差。
首先我们可以看到我们的MyISAM存储引擎中有以下三个文件:
其中.frm文件表示我们表的结构,.MYD文件表示我们MyISAM的表数据,.MYI文件表示我们MyISAM的索引,所以它的表的数据和索引是通过非聚合的方式储存的。
其次聚集索引的结构如下,我们可以清晰看到数据和索引存储是不在同一个文件之中的
3、什么情况下mysql会索引失效
①where 后面使用函数 ②使用or条件③ 模糊查询 %放在前边 ④类型转换 ⑤组合索引 (最佳左前缀匹配原则)
4、什么是联合索引?以及其优点?
联合索引:是指两个或更多个列上的索引被称作联合索引,联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持(a) | (a,b)| (a,b,c )3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
优点:
①减少开销
建一个联合索引(a,b,c),实际相当于建了(a),(a,b),(a,b,c)三个索引.每多一个索引,都会增加写操作的开销和磁盘空间的开销.对于大量数据的表,使用联合索引会大大的减少开销!
②效率高
索引列多,通过联合索引筛选出的数据越少。
③覆盖索引
对联合索引(a,b,c),如果有如下sql的 select a,b,c from table where a='xxx' and b='xx'; 那么mysql可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io操作。在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。
5、什么是索引下推、回表查询、索引覆盖
①:回表查询
当我们的SQL查询要的是全部数据,无法从普通索引里面去获得时,需要做二次查询,通过聚集索引中把所有的数据取出来。这个过程就是回表查询。如下图所示:
如图所以,假设有个user表,里面包含id、name、phone、age这些字段,我们以name建立普通索引,那么此时就会以name的数据经过B+树算法形成了B+Tree,存储到硬盘,如图中右图所示,其叶子节点存的是最终数据包含name(当前索引列的数据)、id(主键列的数据),非叶子节点存储的是一个键值,通过键值定位到最终的数据。此时我们的查询语句是select * from user where name = '***',这时执行流程:先name形成的二叉树查数据,找到name和id;其次,我们需要的是完整数据(select *),就会通过id去我们的聚簇索引上去查的最终完整的数据。这个过程就是回表。
(PS:对于主键索引的树,如果用户设置了主键则会生成主键索引;若没有主键,Innodb会优先选择一个unique键作为主键;若主键和unique都没有的话,则Innodb会自动为用户添加一个叫做DB_ROW_ID的键作为默认主键,只不过这个键我们看不见。所以对于Innodb来讲主键索引一定是存在的。)
②:索引下推
索引下推:简称ICP,是在MySQL5.6的版本上推出,用于优化查询。
用以下案例做个讲解:
select * from student where name like '李%' and age=18;
未设置索引下推的情况:
首先设置了index(name,age)那么在执行语句时,根据最左前缀法则,该语句搜索索引树时,只能匹配到名字里第一个字为李的记录,接下来从该记录开始,逐个回表,到主键索引上找到相应的记录,再和age这个字段做比较看值是否合适。
如上图所示,未配置索引下推,那么在语句执行时,先找到姓李的用户,而不会看age的值,然后分别去主键索引中根据id查询数据,再结合age做过滤,一共要回表4次。
若做了索引下推:
Innodb在(name、age)索引内部就做了age是否为18的判断,对于不符合的数据直接跳过,减少了回表的次数,从而提高整体的性能。如下图所示:
③:索引覆盖
索引覆盖:是一种避免回表查询的优化策略,只需在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。
实现方式:将查询的字段建立 普通索引或者联合索引,这样就可以直接返回索引中的数据,不需要通过聚集索引去定位行记录,避免了回表的情况发生。案例上面那个联合索引的优点提到。
注意事项:
如果一个索引包含了所需的查询的所有字段的值(不需要回表),这个索引就是覆盖索引。
MySQL只能使用B+Tree索引做覆盖索引(因为只有B+Tree能储存索引列值)。
七、总结
这篇博客记录索引的一些基本原理,基本使用以及常见的面试题。通过博客的记录方便博主后期的复习,也希望对大家有所帮助,记得点赞、关注,支持博主一波哦~,后期还有更多内容!
相关文章:

【MySQL】如何理解索引(高频面试点)
一、前言 首先这个博客会介绍一些关于MySQL中索引的基本内容以及一些基本的语法,当然里面也会有些常见的面试题的解答。 二、关于索引 1、概念 索引是一种能够帮助MySQL高效的去磁盘检索数据的一种数据结构。在MySQL的Innodb存储引擎中呢,采用的是B树的…...
NXP实战笔记(四):S32K3xx如何产生中心对称三相六路波形
目录 1、概述 1.1、理论基础 2、RTD实现 2.1、Emios时基配置 2.1.1、EmiosMcl 2.1.2、EmiosCommon 2.2、Emios PWM配置 2.3、TRGMUX 2.4、LCU 2.5、外设信号配置 3、代码实现 4、测试结果 1、概述 电机控制中需要产生三相六路SVPWM进行占空比与周期调制,怎么通过RT…...

关于uniapp H5应用无法在触摸屏正常显示的处理办法
关于uniapp H5应用无法在触摸屏正常显示的处理办法 1、问题2、处理3、建议 1、问题 前几天, 客户反馈在安卓触摸大屏上无法正确打开web系统(uni-app vue3开发的h5 应用),有些页面显示不出内容。该应用在 pc 端和手机端都可以正常…...

Stable Diffusion 3 发布,AI生图效果,再次到达全新里程碑!
AI生图效果,再次到达全新里程碑! Prompt:Epic anime artwork of a wizard atop a mountain at night casting a cosmic spell into the dark sky that says "Stable Diffusion 3" made out of colorful energy 提示(意译…...
单例模式怎样实现单例(独例)?
在类定义中加入私有属性 __init__flag Ture,在随后的初始化处理中,判断该属性为真时进行相应的初始化操作,否则,跳过相应的初始化操作。这个机制,保证在进行后续的调用时,不再占用额外的内存开销。 当然了,…...

MySQL——基础内容
目录 第01章_数据库概述 关系型数据库(RDBMS)——表、关系模型 非关系型数据库(非RDBMS) 表、记录、字段 表的关联关系 一对一关联 一对多关系 多对多 自我引用 第02章_MySQL环境搭建 登录命令 常用命令 show databases; create database use 数据库名 show tables 第03章…...

node 之 初步认识
思考:为什么JavaScript可以在浏览器中被执行 代执行的js代码——JavaScript解析引擎 不同的浏览器使用不同的JavaScript解析引擎 Chrome 浏览器 》 V8 Firefox浏览器 》OdinMonkey(奥丁猴) Safri浏览器 》JSCore IE浏览器 》Chakra(查克拉) e…...

css复习
盒模型相关: border:1px solid red (没有顺序) 单元格的border会发生重叠,如果不想要重叠设置 border-collapse:collapse (表示相邻边框合并在一起) padding padding影响盒子大小的好处使用 margin应用: 行内或行内块元素水…...

HTML5和CSS3提高
一、HTML5的新特性 增加了一些新的标签,新的表单,新的表单属性,IE9以上版本的浏览器才支持 注意: 这些语义化标准主要针对搜索引擎的 新标签可以使用多次 在IE9中需要把这些元素转化为块级元素 新增的多媒体标签 主要包含两个…...

感受2024生物发酵展示会-明章机械
参展企业介绍 温州明章机械有限公司是一家专业从事搅拌传动装置机械密封,减速机,机架,联轴器及相关配件。设计、开发及生产的服务型高新技术企业公司,座落于浙江省温州市瓯海区娄桥镇高新工业园区豪新路42号,交通位置…...

算法打卡day1|数组篇|Leetcode 704.二分查找、27.移除元素
数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合,可以方便的通过下标索引的方式获取到下标下对应的数据。 1.数组下标都是从0开始的。 2.数组内存空间的地址是连续的。 正是因为数组的在内存空间的地址是连续的,所以我们在删除或者增添…...
什么是高阶组件
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。简单来说,高阶组件就是一个函数,该函数接受一个组件作为参数,并返回一个新的组件。这个新的组件会使用你传给它的组件作为子组件。 高阶组件并不是真的组件…...
python实现裂区试验方差分析
方差分析(Analysis of Variance,ANOVA)是一种统计方法,用于比较三个或三个以上组别的平均值是否存在显著差异。它通过比较组内变异和组间变异的大小来判断组别间的平均值是否有显著差异。 方差分析通常用于以下情况: …...
Vue v-for、v-if、v-show常见问题
vue使用v-for遍历对象时,是按照什么顺序遍历的?如何保证顺序? 会先判断对象是否存在iterator接口,如果有循环执行next()方法。 没有iterator的情况下,会调用Object.Keys()方法,在不同的浏览器中ÿ…...
GPT技术在学术研究中的革命性应用:开启论文创作新篇章
在学术界,撰写高质量的论文一直是一个挑战性的任务,它不仅需要深厚的专业知识,还要求良好的文献综述能力、数据分析技巧以及清晰的表达能力。近年来,随着人工智能技术的飞速发展,尤其是生成式预训练变换器(…...
【K8s】-- 描述容器中 pod 的状态
命令:kubectl describe pod -n 你的namespace名称 pod 名称 举例:kubectl describe pod -n my-flink --context prod-5 test-record-all-new-mc-taskmanager-1-1 Name: test-record-all-new-mc-taskmanager-1-1 Namespace: ky-flink Pri…...

使用yolo-seg模型实现自定义自动动态抠图
yolov8导航 如果大家想要了解关于yolov8的其他任务和相关内容可以点击这个链接,我这边整理了许多其他任务的说明博文,后续也会持续更新,包括yolov8模型优化、sam等等的相关内容。 YOLOv8(附带各种任务详细说明链接) …...

FairyGUI × Cocos Creator 3.x 场景切换
前言 前文提要: FariyGUI Cocos Creator 入门 FairyGUI Cocos Creator 3.x 使用方式 个人demo:https://gitcode.net/qq_36286039/fgui_cocos_demo_dust 个人demo可能会更新其他代码,还请读者阅读本文内容,自行理解并实现。 官…...

【Java程序设计】【C00288】基于Springboot的篮球竞赛预约平台(有论文)
基于Springboot的篮球竞赛预约平台(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的篮球竞赛预约平台 本系统分为前台功能模块、管理员功能模块以及用户功能模块。 前台功能模块:用户进入到平台首页&a…...
textbox文本框跨线程写入,扩展textobx控件
在Windows Forms中,由于UI控件不是线程安全的,直接跨线程访问和修改UI控件通常会导致不可预测的行为或异常。TextBox 控件同样不能直接从非创建它的线程进行写入。为了安全地在不同线程间更新 TextBox 控件的内容,你可以使用控件的 Invoke 方…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...