MySQL经典面试题:谈一谈对于数据库索引的理解~~

文章目录

  • 什么是索引?
  • 为什么要引入索引?
  • 引入索引的代价
  • 操作索引的SQL语句
  • 索引背后的数据结构
    • B树
    • B+ 树
  • 回顾思考
  • ☁️结语


什么是索引?

数据库中的索引,就相当于一本书的目录。
什么是书的目录?相信大家都并不陌生,一本书最前面的几页,一般就是目录,如果你想找到某个章节,你就可以通过目录快速定位过去。
同理,在数据库中通过索引,我们就可以快速找到要查询的数据(索引的作用)。

为什么要引入索引?

在数据库中 select 这样的查询操作,默认是按照“遍历”的方式,来完成查询的。

比如,指定where语句,条件查询,遍历每一行,把这一行数据代入到条件中,看是否成立,成立就留下,不成立就pass掉。

遍历的复杂度是O(n),但是要注意,此处的每一次取一行,都是要读硬盘的!!虽然也是O(n),但是它和内存操作的O(n)是有本质区别的~~在硬盘上进行操作,比在内存上进行操作,速度要差了好几个数量级呐!!差距还是非常大的。通过一行一行遍历,这样的操作,就会很慢,非常消耗数据库的资源,这也就使数据库能处理的请求量更少了。因此,为了加快查询速度,就需要在数据库中建立索引。
所谓的“索引”就相当于是在数据库中,构建一个特殊的“目录”(一系列特定的数据结构,在硬盘上的),通过这样的数据结构,加快查询的速度,尽可能避免对数据库的遍历操作。

大家应该都用过everything这个软件吧,everything其实就是针对硬盘文件,进行搜索的,那为啥它能查找的这么快?这是因为everything提前把硬盘上的文件数据,构成了特定的数据结构,查询的时候不必遍历了,直接就能进行快速查询。

引入索引的代价

虽然索引这么好,但是也付出了一点的代价。

  1. 引入索引,需要消耗额外的存储空间。
    举个例子来方便理解:假设你有一本词典,词典特别厚(上千页),查词的时候肯定要通过目录来查,这个时候,你仔细观察一下目录的页数,词典的目录 可能就是厚厚的一打。印目录也需要纸张呀~

  2. 引入索引之后,确实能提高查询的效率,但是可能会影响到增删改的效率。有时候会变慢,比如在进行增删改的时候,需要同步的更新维护索引,更新过程肯定是有额外的开销的;有时候会变快,比如通过条件判断的方式来删除,而删除操作的背后就有查找操作,而索引可以帮我们快速定位;有的时候没有变化。

由此看来,索引这个东西,有利有弊,但是即使如此,我们在实际开发中,还是比较鼓励使用索引的。

原因:

  1. 存储空间(硬盘)往往不是主要矛盾,大不了多加几个。
  2. 索引对于增删改也不一定都是负面影响,也可能会触发一些正面效果,另一方面,很多业务场景,查询的频率比增删改要高很多…

操作索引的SQL语句

  1. 查看索引
show index from 表名;

MySQL会给主键自动生成索引,不需要我们手动创建。
所谓的“索引”是按照 列 的方式来创建的,可以给某个列创建索引,只有在对这个列进行条件查询的时候,索引才能够生效,才能够提升查询速度~~
一个表允许有多个索引(一本词典可能有多种目录(拼音目录、部首目录、笔画目录…))
除了主键之外,unique 和 foreign key 也会自带索引~~这也很容易理解,在子表中插入\修改,需要查询父表;在父表中进行修改\删除,也需要查询子表

  1. 创建索引
create index 索引名 on  表名(列名);

创建索引也是一个“危险操作”
如果是针对空表,或者表中的数据比较少(几千、几万…),此时创建索引就谈不上危险不危险。
一旦表的数据量比较大,千万级别…此时创建索引操作,就可能会触发大量的硬盘IO,直接把机器就搞的卡死住了,所以一定要在最初创建表的时候,提前规划好这个表要有哪些索引。

如果就是要创建呢?
可以再申请一台机器,将旧库的数据导入到新库当中,等数据全都导入完毕之后,再切换我们访问数据库的那个程序,让他从访问旧库,变成访问新库。

  1. 删除索引
drop index 索引名 on 表名;

它只能删除,我们自己创建的索引,不能删除MySQL自动生成的(主键、外键、unique…)。

删除索引也是危险操作!!
要能够慎重对待~

索引背后的数据结构

所谓的“构建索引”其实就是引入一些数据结构,对数据进行存储,从而提高查找的速度。

二叉搜索树和哈希表,都不适合给数据库做索引

  1. 二叉搜索树,最大的问题在于“二叉”要保存的元素多的时候,就会使整个树的高度变的比较高,一旦高度高了,比较次数就会增多~~要知道这是在硬盘上进行的比较,每多比较一次,都是很伤的!!

  2. 哈希表,最大的问题在于,只能进行“相等”查询,无法进行 > < 这样的“范围查询”,也无法进行like模糊查询。哈希表是要通过哈希函数,把查询的key映射成数组下标,不是说key1 < key2 => hash(key1) < hash(key2);

B树

B+树,为数据库量身定制的数据结构。
要想了解B+树,首先要对B树有一定的了解,B树,也可以写作B - 树(这里 - 不是减号,而是连接符)

B树其实就是N叉搜索树,每个节点,可以有多个子树了(树的度是N)
这样就可以降低树的高度了~每个节点上就不是存储一个key值了,而是多个了

在这里插入图片描述

某个节点上保存了N个key就能延伸出N+1个子树了,此时,进行查询的时候,针对每个节点,都需要比较多次,才能确定下一步走哪个区间~~

有人就要问了此时虽然高度降低了,但是每个节点的比较次数变多了,真的能比二叉树有优势吗?
答:其实优势还是很大的!!每个节点,访问的时候是一次硬盘IO就可以了~~
和某个节点进行比较的时候,是先一次硬盘IO,把所有的这个节点上的内容都读取出来,接下来的比较就都是在内存中进行的了

注意:这里的主要目的,不是为了减少比较的次数,而是要减少硬盘IO的次数

B+ 树

B+树是针对B树做出的进一步改进的数据结构~~

在这里插入图片描述

B+树也是N叉搜索树

  1. 不同于B树,B树是有N个key,划分成N+1个区间,B+树是有N个key,划分出N的区间~

  2. 父节点中的key值,会在下面的子节点中再次出现(以子节点中的最大值的身份)~~ 重复出现的做法,看起来好像是浪费空间,实际上非常有用~~所有叶子结点,就构成了整个树数据的全集!!

  3. B+树把叶子节点,像链表一样首尾相连了~~此时,进行“范围查询”就会非常方便!!

B+ 树的优势:

  1. N叉搜索树,高度比较低,此时硬盘IO次数就比较少
  2. 叶子结点是全集,并且用链表结构连接,非常便于进行范围查询~~
  3. B+树,所有的查询都是要落到叶子结点上完成的~~并且任何一次查询,经历的IO次数和比较次数都是差不多的,查询的开销是稳定的~~(稳定其实是一个很大的优势!!稳定意味着,成本是容易被预估出来的~)
  4. 由于B+树,叶子结点是全集,非叶子结点上不必存储“数据行”(数据库中的“表”只是一个逻辑上的结构,在物理上并非是一个真正意义的表~物理上就是通过B+树这样的结构来组织的~),只需要存储索引列的key即可。这使得非叶子结点,消耗的空间较少,甚至这样的数据可以直接全部都加载到内存中~~这样又能进一步减少硬盘IO的次数~~

回顾思考

  1. 索引是啥,它是解决啥问题的?
  2. 索引付出了什么代价?
  3. 如何使用 sql 操作索引,是否又注意事项?
  4. 索引背后的数据结构? => B+树的特点和优势?

解答:

  1. 索引是啥,它是解决啥问题的?
    索引相当于书的目录,能够提高查询的速度

  2. 索引付出了什么代价?

    1. 需要更多的存储空间
    2. 可能会影响增删改的效率(不一定会影响)
      整体来说,索引利大于弊,日常开放中还是会经常使用的
  3. 如何使用 sql 操作索引,是否又注意事项?

    1. show index from 表名;
      查看索引(主键、外键、unique会自动生成索引)
    2. create index 索引名 on 表名(列名);
      给指定列创建索引
    3. drop index 索引名 on 表名;
      删除索引
    4. 索引是针对列来创建的,后续查询的时候,查询条件使用的列和索引列匹配,索引才能生效,才能提高效率。
    5. 针对一个比较大的表,创建\删除索引,是非常危险的,可能会除法大量的硬盘IO,把机器高挂了
  4. 索引背后的数据结构? => B+树的特点和优势?

    1. 特点:
      1. N叉搜索树,每个节点上包含N个 key,划分出N个区间
      2. 每个父节点中的元素,都会下沉到子节点中,作为该子节点中最大值的角色来存在
      3. 叶子结点这一层就构成了数据集合的全集
      4. 使用类似于链表这样的结构,把叶子节点串起来
    2. 优势
      1. N叉搜索树,高度比较低,降低了硬盘IO次数
      2. 范围查询非常方便和高效
      3. 所有的查询都落到叶子节点上,开销非常稳定,容易预估成本
      4. 叶子节点存储数据行,非叶子节点只存储索引列的key值,非叶子节点占据空间小,可以加载到内存中,进一步减少查询时IO的访问次数。

☁️结语

请给自己些耐心,不要急于求成。
山外青山楼外楼,莫把百尺当尽头。
保持空杯心态加油努力吧!


最后的最后,推荐一个数据结构可视化网站,很方便、很好用,很直观。
点击直达 => 数据结构可视化网站


都看到这里啦!真棒(*^▽^*)

可以给作者一个免费的赞赞吗,这将会鼓励我继续创作,谢谢大家

如有纰漏或错误,欢迎指正


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【三】Linux网络配置详解

在RHEL 7系统中配置网络的方法有好几种&#xff0c;咱们这边先讲一下使用图形化工具和修改配置文件这两种方法来配置&#xff0c;其他方法大家可以下去自己研究研究。 一、使用图形化方式配置&#xff1a; 在电脑左上角开始一次点击Applications、System Tools、Settings&…

【Flask-项目运行】解决用本机IP访问不到flask项目而用localhost可以访问到的问题

文章目录 一、问题描述二、解决办法 一、问题描述 使用 localhost 或 127.0.0.1 能访问到项目&#xff1a; 但是使用局域网 IP 访问不到&#xff1a; 二、解决办法 只需要在 app.py 中修改一行代码&#xff1a; run方法添加 host 参数指明全部 ip 可访问。

B端数据看板,其实数据可以更美的。

B端数据看板可以通过设计来提升其美观度。 色彩和配色方案&#xff1a; 选择适合品牌和数据类型的色彩搭配方案。使用渐变色、明亮的色调和对比度来突出重要的数据指标。 数据可视化&#xff1a; 使用图表、图形和数据图像来呈现数据&#xff0c;使其更易于理解和解读。选择…

2024会声会影全新旗舰版,下载体验!

在当今数字时代&#xff0c;视频内容已成为最受欢迎的媒介之一。无论是个人娱乐、教育还是商业推广&#xff0c;优秀的视频制作都是吸引观众的关键。为了满足广大用户对高质量视频制作软件的需求&#xff0c;我们隆重推出了会声会影2024最新旗舰版。这款软件不仅集成了最先进的…

手撸 串口交互命令行 及 AT应用层协议解析框架

在嵌入式系统开发中&#xff0c;命令行接口&#xff08;CLI&#xff09;和AT命令解析是常见的需求。CLI提供了方便的调试接口&#xff0c;而AT命令则常用于模块间的通信控制。本文将介绍如何手动实现一个串口交互的命令行及AT应用层协议解析框架&#xff0c;适用于FreeRTOS系统…

【数据结构】顺序表专题(学习记录)

正文开始 课前预备 1. 课程目标 C语言语法基础到数据结构与算法&#xff0c;前⾯已经掌握并具备了扎实的C语言基础&#xff0c;为什么要学习数据结构课程&#xff1f;⸺通讯录项目 2. 需要的储备知识 简单了解&#xff0c;通讯录具备增加、删除、修改、查找联系⼈等操作。要想…

Linux进程无法被kill

说明&#xff1a;记录一次应用进程无法被kill的错误&#xff1b; 场景 在一次导出MySQL数据时&#xff0c;使用下面的命令&#xff0c;将数据库数据导出为.sql文件&#xff0c;数据量大&#xff0c;导出时间长&#xff0c;于是我就将服务器重启了。 mysqldump -u username -…

队列及其应用

实验内容 请设计一个简单的模拟银行排队系统&#xff0c;要求程序具有以下4项菜单&#xff1a; 1.取号。选择该菜单后&#xff0c;为客户产生一个排队号。 2.叫号。选择该菜单后&#xff0c;显示可服务的客户排队号。 3.查看队伍。从队首到队尾列出所有排队客户的排队号。 4.退…

Vue 学习笔记 总结

Vue.js 教程 | 菜鸟教程 (runoob.com) 放一下课上的内容 Vue练习 1、练习要求和实验2的用户注册一样&#xff0c;当用户输入后&#xff0c;能在下方显示用户输入的各项内容&#xff08;不需要实现【重置】按钮&#xff09; 2、实验报告中的实验小结部分来谈谈用JS、jQuery和…

流量分析——一、蚁剑流量特征

君衍. 一、Webshell特征流量分析二、环境介绍三、使用Wireshark进行流量分析1、环境说明2、HTTP追踪流分析3、蚁剑请求体中代码块解读 四、使用BurpSurite进行流量分析1、环境配置2、抓包分析 六、总结 一、Webshell特征流量分析 对于重保、护网等攻防演练的防守方来说&#x…

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成 学习前言源码下载地址EasyAnimate V2简介技术储备Diffusion Transformer (DiT)Motion ModuleU-VITLora 算法细节算法组成视频VAE视频DIT 数据处理视频分割视频筛选视频描述 模型训练视频VAE视频D…

【数智化CIO展】吉家宠物CIO张志伟:深度挖掘数据价值是数字化发展趋势,才能实现企业精细化运营...

张志伟 本文由吉家宠物CIO张志伟投递并参与由数据猿联合上海大数据联盟共同推出的《2024中国数智化转型升级优秀CIO》榜单/奖项评选。丨推荐企业&#xff1a;观远数据 大数据产业创新服务媒体 ——聚焦数据 改变商业 中国“宠物经济”热潮不断攀升&#xff0c;国内宠物市场的竞…

InnoDB存储引擎非常重要的一个机制--MVCC(多版本并发控制)

Mysql是如何实现隔离性的&#xff1f;&#xff08;锁MVCC&#xff09; 隔离性是指一个事务内部的操作以及操作的数据对正在进行的其他事务是隔离的&#xff0c;并发执行的各个事务之间不能相互干扰。隔离性可以防止多个事务并发执行时&#xff0c;可能存在交叉执行导致数据的不…

Android 如何保证开启debug模式之后再启动

很多时候会需要debug看Android启动时候的一些数据&#xff0c;但很多时候会存在自己开启debug后app已经过了自己要debug的那段代码的时机了。 那么怎么样可以保证一定能让启动后不会错过自己要debug的那段代码执行的时机呢&#xff1f; 可以用下面这行命令&#xff0c;其中co…

记忆化搜索汇总

记忆化搜索简介 记忆化搜索&#xff08;Memoization Search&#xff09;&#xff1a;是一种通过存储已经遍历过的状态信息&#xff0c;从而避免对同一状态重复遍历的搜索算法。 记忆化搜索是动态规划的一种实现方式。在记忆化搜索中&#xff0c;当算法需要计算某个子问题的结果…

Nginx+Tomcat负载均衡、动静分离集群

目录 1.Nginx负载均衡 1.1 负载均衡概念 1.2 负载均衡原理 1.3 Nginx配置反向代理 1.3.1 反向代理概念 1.3.2 反向代理主要参数 2.Nginx动静分离 2.1 动静分离的概念 2.2 Nginx 静态处理优势 2.3 动静分离原理 3. NginxTomcat动静分离的实验设计 3.1 准备三台虚拟机…

Java速成要多久?这篇文章告诉你答案!

Java速成要多久&#xff1f;这篇文章告诉你答案&#xff01; Java作为一门用途广泛且经久不衰的编程语言&#xff0c;吸引了无数学习者的目光。许多人希望能够快速掌握Java&#xff0c;以便进入软件开发行业或者提升自身的竞争力。那么&#xff0c;Java速成究竟要多久呢&#x…

【遗传算法】【机器学习】【Python】常见交叉方法(二)、多点交叉和均匀交叉

一、遗传算法流程图 交叉过程即存在于上图的”交叉“&#xff08;crossover&#xff09;步骤中。 二、多点交叉 多点交叉的原理就是&#xff0c;随机地从父代两个基因型中&#xff0c;选择n个位点进行交换&#xff0c;其中n小于等于父代基因型长度&#xff08;假设双亲基因长…

基于小波变换和峰值搜索的光谱检测matlab仿真,带GUI界面

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于小波变换和峰值搜索的光谱检测matlab仿真,带GUI界面.对光谱数据的成分进行提取&#xff0c;分析CO2&#xff0c;SO2&#xff0c;CO以及CH4四种成分比例。 2.…

【越界写null字节】ACTF2023 easy-netlink

前言 最近在矩阵杯遇到了一道 generic netlink 相关的内核题&#xff0c;然后就简单学习了一下 generic netlink 相关概念&#xff0c;然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成…