【MySQL数据库】索引到底是什么,怎么创建索引的效率最高

news2024/9/22 4:08:15

面试官我看你简历上写了MySQL,对MySQL InnoDB引擎的索引了解吗?

候选者:嗯啊,使用索引可以加快查询速度,其实上就是将无序的数据变成有序(有序就能加快检索速度)

候选者:在InnoDB引擎中,索引的底层数据结构是B+树

面试官那为什么不使用红黑树或者B树呢?

候选者:MySQL的数据是存储在硬盘的,在查询时一般是不能「一次性」把全部数据加载到内存中

候选者:红黑树是「二叉查找树」的变种,一个Node节点只能存储一个Key和一个Value

候选者:B和B+树跟红黑树不一样,它们算是「多路搜索树」,相较于「二叉搜索树」而言,一个Node节点可以存储的信息会更多,「多路搜索树」的高度会比「二叉搜索树」更低。

候选者:了解了区别之后,其实就很容易发现,在数据不能一次加载至内存的场景下,数据需要被检索出来,选择B或B+树的理由就很充分了(一个Node节点存储信息更多(相较于二叉搜索树),树的高度更低,树的高度影响检索的速度)

候选者:B+树相对于B树而言,它又有两种特性。

候选者:一、B+树非叶子节点不存储数据,在相同的数据量下,B+树更加矮壮。(这个应该不用多解释了,数据都存储在叶子节点上,非叶子节点的存储能存储更多的索引,所以整棵树就更加矮壮)

候选者:二、B+树叶子节点之间组成一个链表,方便于遍历查询(遍历操作在MySQL中比较常见)

img

候选者:我稍微解释一下吧,你可以脑补下画面

候选者:我们在MySQL InnoDB引擎下,每创建一个索引,相当于生成了一颗B+树。

候选者:如果该索引是「聚集(聚簇)索引」,那当前B+树的叶子节点存储着「主键和当前行的数据」

候选者:如果该索引是「非聚簇索引」,那当前B+树的叶子节点存储着「主键和当前索引列值」

候选者:比如写了一句sql:select * from user where id >=10,那只要定位到id为10的记录,然后在叶子节点之间通过遍历链表(叶子节点组成的链表),即可找到往后的记录了。

候选者:由于B树是会在非叶子节点也存储数据,要遍历的时候可能就得跨层检索,相对麻烦些。

候选者:基于树的层级以及业务使用场景的特性,所以MySQL选择了B+树作为索引的底层数据结构。

候选者:对于哈希结构,其实InnoDB引擎是「自适应」哈希索引的(hash索引的创建由InnoDB存储引擎引擎自动优化创建,我们是干预不了)

面试官:嗯…那我了解了,顺便想问下,你知道什么叫做回表吗?

候选者:所谓的回表其实就是,当我们使用索引查询数据时,检索出来的数据可能包含其他列,但走的索引树叶子节点只能查到当前列值以及主键ID,所以需要根据主键ID再去查一遍数据,得到SQL 所需的列

候选者:举个例子,我这边建了给订单号ID建了个索引,但我的SQL 是:select orderId,orderName from orderdetail where orderId = 123

候选者:SQL都订单ID索引,但在订单ID的索引树的叶子节点只有orderId和Id,而我们还想检索出orderName,所以MySQL 会拿到ID再去查出orderName给我们返回,这种操作就叫回表

img

候选者:想要避免回表,也可以使用覆盖索引(能使用就使用,因为避免了回表操作)。

候选者:所谓的覆盖索引,实际上就是你想要查出的列刚好在叶子节点上都存在,比如我建了orderId和orderName联合索引,刚好我需要查询也是orderId和orderName,这些数据都存在索引树的叶子节点上,就不需要回表操作了。

面试官既然你也提到了联合索引,我想问下你了解最左匹配原则吗?

候选者:嗯,说明这个概念,还是举例子比较容易说明

候选者:如有索引 (a,b,c,d),查询条件 a=1 and b=2 and c>3 and d=4,则会在每个节点依次命中a、b、c,无法命中d

候选者:先匹配最左边的,索引只能用于查找key是否存在(相等),遇到范围查询 (>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找

候选者:这就是最左匹配原则

img

面试官嗯嗯,我还想问下你们主键是怎么生成的?

候选者:主键就自增的

面试官那假设我不用MySQL自增的主键,你觉得会有什么问题呢?

候选者:首先主键得保证它的唯一性和空间尽可能短吧,这两块是需要考虑的。

候选者:另外,由于索引的特性(有序),如果生成像uuid类似的主键,那插入的的性能是比自增的要差的

候选者:因为生成的uuid,在插入时有可能需要移动磁盘块(比如,块内的空间在当前时刻已经存储满了,但新生成的uuid需要插入已满的块内,就需要移动块的数据)

面试官:OK…

img

本文总结

  • 为什么B+树?数据无法一次load到内存,B+树是多路搜索树,只有叶子节点才存储数据,叶子节点之间链表进行关联。(树矮,易遍历)
  • 什么是回表?非聚簇索引在叶子节点只存储列值以及主键ID,有条件下尽可能用覆盖索引避免回表操作,提高查询速度
  • 什么是最左匹配原则?从最左边为起点开始连续匹配,遇到范围查询终止
  • 主键非自增会有什么问题?插入效率下降,存在移动块的数据问题

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

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

相关文章

微服务守护神-Sentinel-其他

引言 书接上篇 微服务守护神-Sentinel-热点-授权-系统规则 &#xff0c;上面介绍了Sentinel热点、授权、系统规则&#xff0c;本篇继续来Sentinel 剩下其他操作 自定义异常返回 当触发sentinel流控规则之后&#xff0c; sentinel就干巴巴返回异常信息&#xff0c;单纯的文字…

JVM监控及诊断工具

本文目录命令行jps 查看正在运行的Java进程jstat&#xff1a;查看JVM统计信息jinfo&#xff1a;实时查看和修改JVM配置参数jmap&#xff1a;导出内存映像文件&内存使用情况jhat&#xff1a;JDK自带堆分析工具jstack&#xff1a;打印JVM中线程快照jcmd&#xff1a;多功能命令…

docker、LXC、LXD的区别及传统的虚拟机与操作系统虚拟化的区别

1. 概念解释 1.1. Docker Docker是一个用于在集中式平台上创建、部署和运行应用程序的开源工具。这使得主机的操作系统通过容器运行具有相同Linux内核的应用程序&#xff0c;而不是创建一个完整的虚拟机。使用docker容器不需要考虑Ram和磁盘空间的分配。它能够自己处理这些需…

CopyOnWriteArrayList源码解析

CopyOnWriteArrayList源码解析 简介 我们知道 ArrayList 是线程不安全的&#xff0c;其存在一个古老的线程安全的 Vector&#xff0c;但是由于 Vector 效率太低 (方法都加了synchronzed)&#xff0c;在 JDK1.5 时 Doug Lea 提供了一个效率较高的线程安全的 CopyOnWriteArrayL…

虚拟内存(深入理解计算机系统原书第3版9节)

深入理解计算机系统&#xff08;原书第3版&#xff09;读书笔记&#xff0c;其实就是嚼碎了原文然后把一部分挑了出来摘要&#xff0c;免得读着读着忘了 文章目录前言一、物理和虚拟寻址二、地址空间三、虚拟内存作为缓存的工具1、DRAM缓存的组织结构2、页表3、页命中4、缺页5、…

[附源码]Python计算机毕业设计SSM基于的小区物业管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务框架 SpringCloud微服务架构 微服务保护 33 授权规则 33.1 授权规则

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护33 授权规则33.1 授权规则33.1.1 授权规则33 授权规则 33.1 授权规则 33.1.1 授权规则 看看sen…

康鹏科技将于12月16日上会:曾在纽交所上市,由杨建华家族控股

近日&#xff0c;上海康鹏科技股份有限公司&#xff08;下称“康鹏科技”&#xff09;在上海证券交易所递交招股书&#xff08;上会稿&#xff09;&#xff0c;准备在科创板上市。据贝多财经了解&#xff0c;康鹏科技将于2022年12月16日接受科创板上市委的现场审议。 根据公开信…

基于C++实现(MFC)职工工作量统计系统【100010022】

【职工工作量统计系统设计】 1、问题描述 职工包括姓名、职工号、性别、年龄、所在部门、联系方式等信息。 工作量包括职工号、完成的产品数量等信息。 该设计系统能够对职工的工作量进行统计&#xff0c;并排出名次。注意&#xff0c;一个职工的工作量是可以多次输入的。 2…

Alibaba官方上线,Java并发编程全彩图册(终极版)GitHub已置顶

都说程序员工资高、待遇好&#xff0c; 2022 金九银十到了&#xff0c;你的小目标是 30K、40K&#xff0c;还是 16薪的 20K&#xff1f;作为一名 Java 开发工程师&#xff0c;当能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。然而&#xff0c;提升 Java…

Python图像识别实战(一):实现按数量随机抽取图像复制到另一文件夹(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用&#xff0c;分为分类问题&#xff08;预测值是离散型&#xff09;和回归问题&#xff08;预测值是连续型&#xff09;&#xff08;具体见之前的文章&#xff09;。 从本期开始&#xff0c;我将做一个关于图像识别的…

Qt实现全局鼠标事件监听器-Linux

Qt实现全局鼠标事件监听器-Linux版&#x1f991; var code “bc8d4eb4-a9df-48e9-8028-bbe1ae7fbd05” 文章目录Qt实现全局鼠标事件监听器-Linux版&#x1f991;1、概述&#x1f99e;2、实现效果&#x1f370;3、实现方式&#x1f980;4、关键代码&#x1f366;5、源代码&…

SpringMVC基础篇:第一个MVC程序和细节分析

文章整理自孙哥说SpringMVC&#xff0c;相关课程联系孙哥学习谢谢。第一章&#xff1a;编码开发一&#xff1a;思路分析二&#xff1a;SpringMVC程序编码三&#xff1a;控制器提供多个服务方法四&#xff1a;注意事项第二章&#xff1a;细节分析一&#xff1a;控制器创建次数二…

C++ 【set、map模拟实现】

目录 set概念 set基本使用 map概念 map的使用 map统计次数 operator[] operator[]底层如何实现&#xff1f; set和map迭代器封装 红黑树迭代器基本结构 operator operator-- operator[] 源代码链接 map、set底层都使用平衡搜索树(即红黑树)&#xff0c;容器中的元素…

HanLP 基于朴素贝叶斯 训练 文本分类

一、HanLP 朴素贝叶斯分类器 HanLP 针对文本分类算法已经帮我们实现 朴素贝叶斯法 &#xff0c;用户可以无需关心内部细节&#xff0c;HanLP 也提供了相关自定义训练接口&#xff0c;前提需要将数据集根据分类放到不同的目录中&#xff0c;例如&#xff1a; 官方给出了相关性能…

HanLP 基于SVM支持向量机 训练 文本分类

一、HanLP 基于SVM支持向量机分类器 上篇文章通过朴素贝叶斯文本分类器&#xff0c;训练测试了 搜狗文本分类语料库迷你版 &#xff0c;本篇继续测试SVM支持向量机分类器。 由于HanLP 官方给出的 SVM 分类器依赖了第三方库&#xff0c;没有集成在主项目中&#xff0c;需要拉取…

问题解决(1)——VS中scanf报错怎么解决

目录 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 各位好&#xff0c;博主新建了个公众号《自学编程村》&#xff0c;拉到底部即可看到&#xff0c;有情趣可以关注看看哈哈&#xff0c;关注后还可以加博主wx呦~~~&#xff08;公众号拉到底部就能看到呦~~&am…

Redis【13】-修改数据库后,如何保证Redis与数据库的数据一致性

一、需求起因 在高并发的业务场景下&#xff0c;数据库大多数情况都是用户并发访问最薄弱的环节。所以&#xff0c;就需要使用redis做一个缓冲操作&#xff0c;让请求先访问到redis&#xff0c;而不是直接访问MySQL等数据库。 这个业务场景&#xff0c;主要是解决读数据从Redi…

ARM 代码重定位实战

前言 任务 在 SRAM 中将代码从 0xd0020010 重定位到 0xd0024000。任务解释&#xff1a;本来代码是运行在0xd0020010的&#xff0c;但是因为一些原因我们又希望代码实际是在0xd0024000位置运行 的。这时候就需要重定位了。注解&#xff1a;本练习对代码本身运行无实际意义&…

你都工作两年半了,还不会RabbitMQ?

What is rabbitMQ &#xff1f; RabbitMQ 是一个由 Erlang 语言开发的 AMQP(高级消息队列协议) 的开源实现。 RabbitMQ 是轻量级且易于部署的&#xff0c;能支持多种消息协议。 RabbitMQ 可以部署在分布式和联合配置中&#xff0c;以满足高规模、高可用性的需求。 具体特点包括…