MySQL面试常问问题(索引) —— 赶快收藏

news2024/11/20 7:11:50

目录

1.能简单说一下索引的分类吗?

2.为什么使用索引会加快查询?

3.创建索引有哪些注意点?

4.索引哪些情况下会失效呢?

5.索引不适合哪些场景呢?

6.索引是不是建的越多越好呢?

7.MySQL索引用的什么数据结构了解吗?

8.那一棵B+树能存储多少条数据呢?

9.为什么要用 B+ 树,而不用普通二叉树?

10.为什么用 B+ 树而不用 B 树呢?

11.Hash 索引和 B+ 树索引区别是什么?

12.聚簇索引与非聚簇索引的区别?

13.回表了解吗?

14.覆盖索引了解吗?

15.什么是最左前缀原则/最左匹配原则?

16.什么是索引下推优化?


索引可以说是MySQL面试中的重中之重,一定要彻底拿下。

1.能简单说一下索引的分类吗?

从三个不同维度对索引分类:

索引分类

例如从基本使用使用的角度来讲:

  • 主键索引: InnoDB主键是默认的索引,数据列不允许重复,不允许为NULL,一个表只能有一个主键。

  • 唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。

  • 普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。

  • 组合索引:多列值组成一个索引,用于组合搜索,效率大于索引合并

2.为什么使用索引会加快查询?

传统的查询方法,是按照表的顺序遍历的,不论查询几条数据,MySQL需要将表的数据从头到尾遍历一遍。

在我们添加完索引之后,MySQL一般通过BTREE算法生成一个索引文件,在查询数据库时,找到索引文件进行遍历,在比较小的索引数据里查找,然后映射到对应的数据,能大幅提升查找的效率。

和我们通过书的目录,去查找对应的内容,一样的道理。

索引加快查询远离

3.创建索引有哪些注意点?

索引虽然是sql性能优化的利器,但是索引的维护也是需要成本的,所以创建索引,也要注意:

  1. 索引应该建在查询应用频繁的字段

    在用于 where 判断、 order 排序和 join 的(on)字段上创建索引。

  2. 索引的个数应该适量

    索引需要占用空间;更新时候也需要维护。

  3. 区分度低的字段,例如性别,不要建索引。

    离散度太低的字段,扫描的行数降低的有限。

  4. 频繁更新的值,不要作为主键或者索引

    维护索引文件需要成本;还会导致页分裂,IO次数增多。

  5. 组合索引把散列性高(区分度高)的值放在前面

    为了满足最左前缀匹配原则

  6. 创建组合索引,而不是修改单列索引。

    组合索引代替多个单列索引(对于单列索引,MySQL基本只能使用一个索引,所以经常使用多个条件查询时更适合使用组合索引)

  7. 过长的字段,使用前缀索引。当字段值比较长的时候,建立索引会消耗很多的空间,搜索起来也会很慢。我们可以通过截取字段的前面一部分内容建立索引,这个就叫前缀索引。

  8. 不建议用无序的值(例如身份证、UUID )作为索引

    当主键具有不确定性,会造成叶子节点频繁分裂,出现磁盘存储的碎片化

4.索引哪些情况下会失效呢?

  • 查询条件包含or,可能导致索引失效

  • 如果字段类型是字符串,where时一定用引号括起来,否则会因为隐式类型转换,索引失效

  • like通配符可能导致索引失效。

  • 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效。

  • 在索引列上使用mysql的内置函数,索引失效。

  • 对索引列运算(如,+、-、*、/),索引失效。

  • 索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效。

  • 索引字段上使用is null, is not null,可能导致索引失效。

  • 左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。

  • MySQL优化器估计使用全表扫描要比使用索引快,则不使用索引。

5.索引不适合哪些场景呢?

  • 数据量比较少的表不适合加索引

  • 更新比较频繁的字段也不适合加索引

  • 离散低的字段不适合加索引(如性别)

6.索引是不是建的越多越好呢?

当然不是。

  • 索引会占据磁盘空间

  • 索引虽然会提高查询效率,但是会降低更新表的效率。比如每次对表进行增删改操作,MySQL不仅要保存数据,还有保存或者更新对应的索引文件。

7.MySQL索引用的什么数据结构了解吗?

MySQL的默认存储引擎是InnoDB,它采用的是B+树结构的索引。

  • B+树:只有叶子节点才会存储数据,非叶子节点只存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表。

B+树索引

在这张图里,有两个重点:

  • 最外面的方块,的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(粉色所示)和指针(黄色/灰色所示),如根节点磁盘包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、4、5……、65。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

  • 叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表,可以进行范围查询。

8.那一棵B+树能存储多少条数据呢?

B+树存储数据条数

假设索引字段是 bigint 类型,长度为 8 字节。指针大小在 InnoDB 源码中设置为 6 字节,这样一共 14 字节。非叶子节点(一页)可以存储 16384/14=1170 个这样的 单元(键值+指针),代表有 1170 个指针。

树深度为 2 的时候,有 1170^2 个叶子节点,可以存储的数据为 1170*1170*16=21902400

在查找数据时一次页的查找代表一次 IO,也就是说,一张 2000 万左右的表,查询数据最多需要访问 3 次磁盘。

所以在 InnoDB 中 B+ 树深度一般为 1-3 层,它就能满足千万级的数据存储。

9.为什么要用 B+ 树,而不用普通二叉树?

可以从几个维度去看这个问题,查询是否够快,效率是否稳定,存储数据多少,以及查找磁盘次数。

为什么不用普通二叉树?

普通二叉树存在退化的情况,如果它退化成链表,相当于全表扫描。平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。

为什么不用平衡二叉树呢?

读取数据的时候,是从磁盘读到内存。如果树这种数据结构作为索引,那每查找一次数据就需要从磁盘中读取一个节点,也就是一个磁盘块,但是平衡二叉树可是每个节点只存储一个键值和数据的,如果是 B+ 树,可以存储更多的节点数据,树的高度也会降低,因此读取磁盘的次数就降下来啦,查询效率就快。

10.为什么用 B+ 树而不用 B 树呢?

B+相比较B树,有这些优势:

  • 它是 B Tree 的变种,B Tree 能解决的问题,它都能解决。

    B Tree 解决的两大问题:每个节点存储更多关键字;路数更多

  • 扫库、扫表能力更强

    如果我们要对表进行全表扫描,只需要遍历叶子节点就可以 了,不需要遍历整棵 B+Tree 拿到所有的数据。

  • B+Tree 的磁盘读写能力相对于 B Tree 来说更强,IO次数更少

    根节点和枝节点不保存数据区, 所以一个节点可以保存更多的关键字,一次磁盘加载的关键字更多,IO次数更少。

  • 排序能力更强

    因为叶子节点上有下一个数据区的指针,数据形成了链表。

  • 效率更加稳定

    B+Tree 永远是在叶子节点拿到数据,所以 IO 次数是稳定的。

11.Hash 索引和 B+ 树索引区别是什么?

  • B+ 树可以进行范围查询,Hash 索引不能。

  • B+ 树支持联合索引的最左侧原则,Hash 索引不支持。

  • B+ 树支持 order by 排序,Hash 索引不支持。

  • Hash 索引在等值查询上比 B+ 树效率更高。

  • B+ 树使用 like 进行模糊查询的时候,like 后面(比如 % 开头)的话可以起到优化的作用,Hash 索引根本无法进行模糊查询。

12.聚簇索引与非聚簇索引的区别?

首先理解聚簇索引不是一种新的索引,而是而是一种数据存储方式。聚簇表示数据行和相邻的键值紧凑地存储在一起。我们熟悉的两种存储引擎——MyISAM采用的是非聚簇索引,InnoDB采用的是聚簇索引。

可以这么说:

  • 索引的数据结构是树,聚簇索引的索引和数据存储在一棵树上,树的叶子节点就是数据,非聚簇索引索引和数据不在一棵树上。

聚簇索引和非聚簇索引

  • 一个表中只能拥有一个聚簇索引,而非聚簇索引一个表可以存在多个。

  • 聚簇索引,索引中键值的逻辑顺序决定了表中相应行的物理顺序;索引,索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。

  • 聚簇索引:物理存储按照索引排序;非聚集索引:物理存储不按照索引排序;

13.回表了解吗?

在InnoDB存储引擎里,利用辅助索引查询,先通过辅助索引找到主键索引的键值,再通过主键值查出主键索引里面没有符合要求的数据,它比基于主键索引的查询多扫描了一棵索引树,这个过程就叫回表。

例如:select * from user where name = ‘张三’;

InnoDB回表

14.覆盖索引了解吗?

在辅助索引里面,不管是单列索引还是联合索引,如果 select 的数据列只用辅助索引中就能够取得,不用去查主键索引,这时候使用的索引就叫做覆盖索引,避免了回表。

比如,select name from user where name = ‘张三’;

覆盖索引

15.什么是最左前缀原则/最左匹配原则?

注意:最左前缀原则、最左匹配原则、最左前缀匹配原则这三个都是一个概念。

最左匹配原则:在InnoDB的联合索引中,查询的时候只有匹配了前一个/左边的值之后,才能匹配下一个。

根据最左匹配原则,我们创建了一个组合索引,如 (a1,a2,a3),相当于创建了(a1)、(a1,a2)和 (a1,a2,a3) 三个索引。

为什么不从最左开始查,就无法匹配呢?

比如有一个user表,我们给 name 和 age 建立了一个组合索引。

ALTER TABLE user add INDEX comidx_name_phone (name,age);

组合索引在 B+Tree 中是复合的数据结构,它是按照从左到右的顺序来建立搜索树的 (name 在左边,age 在右边)。

组合索引

从这张图可以看出来,name 是有序的,age 是无序的。当 name 相等的时候, age 才是有序的。

这个时候我们使用 where name= ‘张三‘ and age = ‘20 ‘去查询数据的时候, B+Tree 会优先比较 name 来确定下一步应该搜索的方向,往左还是往右。如果 name 相同的时候再比较age。但是如果查询条件没有 name,就不知道下一步应该查哪个 节点,因为建立搜索树的时候 name 是第一个比较因子,所以就没用上索引。

 

16.什么是索引下推优化?

索引条件下推优化(Index Condition Pushdown (ICP) )是MySQL5.6添加的,用于优化数据查询。

  • 不使用索引条件下推优化时存储引擎通过索引检索到数据,然后返回给MySQL Server,MySQL Server进行过滤条件的判断。

  • 当使用索引条件下推优化时,如果存在某些被索引的列的判断条件时,MySQL Server将这一部分判断条件下推给存储引擎,然后由存储引擎通过判断索引是否符合MySQL Server传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器。

例如一张表,建了一个联合索引(name, age),查询语句:select * from t_user where name like '张%' and age=10;,由于name使用了范围查询,根据最左匹配原则:

不使用ICP,引擎层查找到name like '张%'的数据,再由Server层去过滤age=10这个条件,这样一来,就回表了两次,浪费了联合索引的另外一个字段age

没有使用ICP

但是,使用了索引下推优化,把where的条件放到了引擎层执行,直接根据name like '张%' and age=10的条件进行过滤,减少了回表的次数。

使用ICP

索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少MySQL服务器从存储引擎接收数据的次数。

 

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

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

相关文章

HackTheBox Soccer 通过WebSockets进行SQL注入,Doas与Dstat插件提权

靶机网址&#xff1a; https://app.hackthebox.com/machines/Precious枚举 使用nmap枚举靶机 nmap -sC -sV 10.10.11.194机子开放了22&#xff0c;80和9091端口&#xff0c;我们本地dns解析这个域名 echo "10.10.11.194 soccer.htb" >> /etc/hosts然后fuzz…

SpringBoot启动时无法加载自定义配置文件(根据环境不同,本地和生产)

问题背景 springboot启动的时候总是报找不到ftp_upload.properties. 估计同学该诧异了&#xff0c;明明就是在项目下的config下&#xff0c;为啥找不到呢&#xff1f;我们都知道springboot的配置文件启动加载顺序是&#xff1a; 第一&#xff1a; ./config/(项目根目录下的…

【文献阅读笔记】利用松弛方法解决非凸问题

文章目录如何判断凸函数常见的凸函数复合函数判断是否凸函数对于约束问题使用泰勒公式进行松弛参考文献如何判断凸函数 当满足下面的公式时候可以判断目标函数为凸函数 f(ξx(1−ξ)y)<ξf(x)(1−ξ)f(y)f(\xi x(1-\xi)y)<\xi f(x)(1-\xi)f(y) f(ξx(1−ξ)y)<ξf(x)…

eclipse整合tomcat+maven

eclipse整合tomcatmaven 前提 本地安装好 tomcat 本地安装好 maven 本地选择一个目录作为 eclipse 工作空间 , 即 workspace 我本地 tomcat 版本是 8.5 , maven 版本是 3.6.1 整合tomcat windows —> preferences --> 搜索 Runtime 选择本地对应的 tomcat 版本 (我…

VXLAN技术是什么,谈何打破与大厂项目的技术壁垒

随着IT环境的不断变化以及新技术的快速发展&#xff0c;新的客户需求下&#xff0c;新的隧道协议也随之被引入进来。从GRE到VXLAN、GENEVE&#xff0c;网络虚拟化技术得到迅猛发展。 尤其是在大数据背景下&#xff0c;海量数据的处理对网络中数据中心的虚拟化、数据迁移等问题提…

BitSail issue 持续更新中,快来挑战,赢取千元礼品!

背景介绍 近期&#xff0c;BitSail 社区发布了 Contributor 激励计划第一期&#xff0c;包含众多 issue&#xff0c;吸引了很多热衷开源的小伙伴的加入&#xff0c;详情可查看&#x1f449;https://mp.weixin.qq.com/s/GkGs-EqTV-szvzndMYrG1g Issue 介绍 为了扩展 BitSail …

全面edge浏览器体验优化

前言 使用Windows系统的朋友们肯定都多少会用到edge浏览器&#xff0c;但是你们都真的了解edge的实用功能吗&#xff0c;本文会介绍edge优秀好用的自带功能以及能极大程度提升使用体验的第三方插件&#xff0c;帮助你打造一个用着更加顺手方便的edge浏览器。 自带功能 1、re…

m基于GNN图神经网络的目标匹配分析matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 在一些应用领域数据可以自然而然地表示成图结构&#xff0c;包括 蛋白质组学&#xff0c;图像分析&#xff0c;场景描述 &#xff0c;软件工程&#xff0c;和自然语言处理。最简单的图结构包括单…

车辆信息网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

当谈论 React hook,我们究竟说的是什么?

这个标题很大&#xff0c;但是落点很小&#xff0c;只是我&#xff0c;一个开发者在学习和使用 hooks 中的一点感受和总结。 React hook 的由来 React hook 的由来&#xff0c;其实也可以看作是前端技术不断演进的结果。 在 world wide web 刚刚诞生的洪荒时代&#xff0c;还…

无人机自由飞行测试台 FFT GYRO 600

产品简介 无人机在研制过程中需要不断地进行飞行测试&#xff0c;而测试的过程不是万无一失的&#xff0c;飞行过程中发生任何错误都有可能会导致无人机的损毁或破坏&#xff0c;更严重地甚至会造成外界伤害。 基于此我们推出了无人机的三旋转自由度(3-DOF)飞行平台测试系统&…

标准I/O

1.标准I/O介绍 文件基础 概念&#xff1a; 一组相关数据的有序集合 文件类型&#xff1a; 常规文件 r 目录文件 d 字符设备文件 c 键盘&#xff0c;鼠标 块设备文件 b U盘&#xff0c;SD卡等 管道文件 p 套接字文件 s 符号链接文件 l &#xff08;类似于快捷方式&#xff09;…

【Lua】Lua基础语法

1 Lua 简介 Lua 是一个小巧的脚本语言&#xff0c;用标准C语言编写而成&#xff0c;由巴西里约热内卢天主教大学的 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 三人于 1993 年开发&#xff0c;设计目的是为了灵活嵌入应用程序&#xff0c;实现灵活…

基础IO——缓冲区

文章目录1. 缓冲区理解1.1 缓冲区在哪里1.2 刷新策略2. 标准输出和标准错误2.1 模拟perror1. 缓冲区理解 什么是缓冲区呢&#xff1f; 缓冲区的本质&#xff1a;就是一段内存 为什么要有缓冲区呢&#xff1f; 大家在日常生活中&#xff0c;如果我们想寄东西给朋友&#xff0c…

ELK集群部署---LogStash,Filebeat的部署

1. 环境规划: 主机名IP地址角色node1192.168.56.111 ElasticSearch(master) Zookeeper Kafka node2192.168.56.112 ElasticSearch(slave) Kibana Zookeeper Kafka node3192.168.56.113 ElasticSearch(slave) Zookeeper Kafka node4192.168.56.114 Logstash Filebeat 2. nod…

vue 实现类似甘特图大屏效果

最近在做大屏展示&#xff0c;其中一个需求是展示生产过程中投料情况&#xff0c;效果类似甘特图。 思路&#xff1a;1.先得到整个过程的开始时间startTime和结束时间endTime。计算出整个过长经历的时长。 2.计算横向坐标的开始时间start和结束时间end&#xff0c;坐标的开始时…

五分钟了解GRE是什么,四信GRE相关应用推荐

随着互联网新技术的发展以及智能化水平的提高&#xff0c;各企业对实时数据传输的需求也在不断提升&#xff0c;企业愈发重视数据中心的建设&#xff0c;各类虚拟网络技术相继被引入。今天&#xff0c;我们重点了解下云端“借道”鼻祖&#xff0c;善于“包装”的GRE&#xff0c…

新品上市|四信LTE Cat.1无线数传终端 推进中低速蜂窝典型应用

当前&#xff0c;物联网作为新型信息基础设施&#xff0c;已成为推动制造业、零售业、金融业、服务业等行业数字转型、智能升级、融合创新的重要支撑。《“十四五”信息通信行业发展规划》提出&#xff0c;要推进移动物联网全面发展&#xff0c;推动存量2G/3G物联网业务向NB-Io…

SSM医院病历

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

CentOS7安装git

CentOS7安装git前言一、git介绍二、使用yum安装git1.安装git2.查看git版本3.移除git三、源码包安装git1.安装依赖2.下载源码包3.解压4.git安装5.查看git版本总结前言 CentOS7安装git&#xff0c;刚开始使用yum安装git&#xff0c;发现安装的版本默认是1.8.3.1&#xff0c;如果…