面试怎么回答MySQL索引问题,看这里

news2024/11/26 22:37:18

前言

小A在宿舍里跟哥们开五黑打排位中,突然收到女神小美的消息:“小A,我今天面试碰到索引问题了,我没回答好”。小A顾不上游戏抓紧回复到:“到你宿舍某某咖啡店吧,我帮你一起看下”。

小A抓紧时间换了衣服, 就狂奔而去。电脑上传来了哥们的骂声:”去你大爷的小A,老子晋级赛呢!“。小A心想,不好意思,在女神面前,兄弟如浮云。

小A一路火花带闪电的跑到咖啡店,看到小美也刚到。立马到前台点了两杯咖啡,坐到到了小美对面说到:没事,你用今天面试官问你的问题来问我,我回答一遍给你看看,晚上再给你整理下笔记。

正文

小美认真回想了一下今天被面试官问到的索引问题,开始提问。

索引类型

先简单讲下什么是索引?

索引出现是为了提升数据查询效率,就像字典目录一样。一本一两千页的字典,如果我们只是想查询某个字所在的页数,如果没有目录估计得找一会儿。而目录的存在就是帮助我们快速定位到其具体的页数,而索引就是数据库中的目录,帮助存储引擎快速查询到数据。

MySQL 中索引有哪些类型?

常见有以下三种类型:

  • 主键索引
  • 唯一索引
  • 普通索引

还有其他几种不常用索引类型:

  • 全文索引
  • 空间索引

InnoDB 索引的实现方式有哪些?

有两种方式,分别为 BTreeHash,BTree 在实际使用中更为普遍。主要是 Hash 实现方式类似 HashMap ,有以下几个缺点很难满足业务需求:

  1. 只支持等值查询,无法实现范围查询
  2. 不支持使用索引排序
  3. 不支持模糊查询和前缀匹配
  4. 每次查询都需要回表,无法使用覆盖索引特性
  5. 随着数据量增大,Hash 冲突的概率加大,进而影响效率

索引区别

讲一下常用索引类型之间的区别

常见索引:

  • 主键索引:在 InnoDB 里,也被称为聚簇索引。每个表都只能建一个主键索引(某一个字段),且主键索引字段值不能为 NULL,不能重复。主键索引的B+树叶子结点存储的是数据内容,所以根据主键索引查询时不用涉及到回表。

  • 唯一索引:每个表可以创建多个唯一索引,且可以由多个字段组合而成。唯一索引可以为 NULL,唯一索引整体不能重复。

  • 普通索引:整体和唯一索引类型类似,唯一的区别就是普通索引可以重复。

其中多个字段组成的普通/唯一索引也叫联合索引

而剩余两种索引,大多数场景下不推荐使用:

  • 全文索引:就是将各种信息,文档中所有的文字序列都作为检索对象导致索引文件较大,查询是根据全文索引找出包含检索词汇的信息或文档。
  • 空间索引:对空间数据类型的字段建立的索引,MYSQL 使用 SPATIAL 关键字进行扩展,使其能够在空间数据类型的语法上创建空间索引。

主键索引有哪些点需要注意?

主键索引一般建议采用自增主键的方式,可以避免叶子结点的分裂和合并动作。如果是采用业务字段无法保证有序插入,从而导致频繁的页分裂与页合并,进而影响写入效率。

主键索引占用的空间需要尽可能的小,最好使用 int 或 bigint 类型,因为每个非主键索引的叶子节点都需要存储主键索引值从而进行回表。而主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小。

以上只针对 BTree 实现方式,从性能和存储上考量自增主键更合适。另外如果频繁只使用某个字段进行查询,那建议直接将这个索引设置为主键,可以避免每次查询需要搜索两棵树。

索引优化

什么是回表?

在根据非主键索引查询数据过程中,需要搜索两棵树:

  • 第一次对应非主键索引树的查询,从对应的叶子结点获取到主键ID
  • 第二次为主键索引树的查询,根据前面获取到的主键ID查询到对应数据。

其中回到主键索引树搜索的过程,我们称为回表。

回表有什么方式可以避免?
可以通过覆盖索引来避免回表,比如 SQL 语句如下:

select id from user where name = '小A';

其中id字段为主键,name为非主键索引。那么如上 SQL 语句我们就不需要进行回表,因为id值已经在非主键索引树上存储,可以直接返回查询结果。如果某个非主键索引,已经覆盖了我们的所有查询字段,我们成为覆盖索引

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

你知道最左匹配原则嘛?

上述提到过联合索引的定义,比如我们定义了一个联合索引为(a,b,c)三个字段构成的。当我们执行的查询语句如下:

语句1:select * from user where a = 1 and b = 2 and c = 3;
语句2:select * from user where a = 1 and b = 2;
语句3:select * from user where a = 1 and c = 3;
语句4:select * from user where b = 2 and c = 3;

上述四个语句中,只有语句1、2会使用到联合索引,而语句3,4因为不满足最左匹配原则导致无法使用到联合索引,因为索引项是按照索引定义里面出现的字段顺序排序的。

在建立联合索引的时候,如何安排索引内的字段顺序是需要根据业务实际情况来安排。如有上诉的联合索引(a,b,c),我们就不需要再额外创建索引(a),(a,b)。但是如果你想使用(b,c)的联合索引就需要再额外创建,这时候你应该考虑(a),(a,b)索引顺序是否有业务需求,是否通过修改索引的顺序为(b,c,a),就可以减少维护一个索引。

如果通过调整联合索引顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的,其次需要考虑的是空间。如果索引(a),(b),(a,b)业务上都需要使用,就根据a和b的字段大小来判断。如果b字段更大,那就创建索引为(b,a)的联合索引和(a)的单字段索引。

那索引下推呢?

索引下推是 MySQL 5.6 引入的优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

还是以联合索引为(a,b,c)为例,执行如下查询语句:

select * from user where a = 1 and c = 3;

通过上面的最左匹配原则我们知道,这里只会使用到联合索引(a,b,c)的a字段,在5.6版本之前就需要将满足a的所有数据根据主键开始一个个回表。到主键索引上找出数据行,再对比字段值。

而有了索引下推,就可以直接在使用联合索引(a,b,c)先通过索引查找到所有满足 a = 1 的数据再依次遍历过滤掉 c != 3 的数据,通过减少回表次数从而优化查询效率。

前缀匹配和前缀索引又是什么呢?

前缀匹配其实是包含在最左匹配原则中的,针对索引字段是字符串。例如普通索引(name),name字段类型为 varchar(32) ,执行如下查询语句:

语句一:select * from user where name = "龙傲天";
语句二:select * from user where name like "龙%";
语句三:select * from user where name like "%傲天";

其中语句一是完全匹配,我们已经知道了。而语句二就是满足最左匹配原则中的前缀匹配,一样可以使用索引查询姓为龙的人。语句三就不满足原则,导致索引失效。

前缀索引:如果列是长字符串,则索引可能占用大量磁盘空间并可能减慢 INSERT 操作速度。根据查询区分度,对字符串的前几个字符创建索引。

获取区分度:select count(distinct left(name, 4))/count(*) from user

就想姓名,中国绝大部分名字都在四个字以内。我们通过查询区分度发现满足当前系统99%的人,就可以创建前缀索引为name(4),而不需要将名字整个字段设为索引,查询效率和索引存储空间都有一定的提升。

索引失效

你知道有那些情况会导致索引失效?

  • 字段判断时使用函数,破坏索引值的有序性或产生隐私转换,导致索引失效
  • 不满足最左匹配原则,联合索引顺序问题导致索引失效
  • IS NULL 可以使用索引,IS NOT NULL 无法使用索引
  • 不等于 != 或者 <> 会导致索引失效
  • OR 前后只要存在非索引的列,都会导致索引失效
  • 不同的字符集进行比较前需要进行转换,会造成索引失效

日常工作中的SQL优化小技巧

  • 尽量不使用 * 查询,尽可能触发索引覆盖,减少回表
  • 不要无限创建索引,索引并不少越多越好,会降低SQL写入性能
  • 不要使用全文模糊搜索,使用前缀匹配
  • 查询尾缀可通过倒序存储,再使用前缀匹配来满足搜索(使用8.0版本的倒序索引就无须创建重复字段)
  • 通过区分度增加前缀索引,降低索引长度
  • 数据库使用的索引不一定是最优解,使用force index强制使用索引(慎用)
  • 尽量避免超过三个表的Join语句,可以通过冗余部分字段解决

结束语

小美对小A不禁又高看了一眼,而小A继续说到:“天色有点晚了,关于索引的BTree数据结构我晚上回去整理发给你”。小美为了答谢想请小A一起吃顿晚饭,而小A义正言辞拒绝到:“不了,我还是抓紧回去整理文章发给你。我怕你明天被问到”,说完就飞奔回宿舍。

各位小A读者,索引你学会了嘛?本文对索引的大部分面试常见问题都讲述到了,篇幅较长,遗留的BTree数据结构后面另起文章补上。

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

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

相关文章

物联公司网页设计制作 简单静态HTML网页作品 静态企业网页作业成品 学生网站模板

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Linux系统部署

Linux系统部署 下载vmware centos7 xshell6 xftp6新建虚拟机&#xff0c;注意设置网络连接&#xff0c;设置登录名&#xff1a;root,密码&#xff1a;root,等待登录&#xff0c;输入用户名和密码&#xff08;注意密码输入不显示&#xff09;登录成功&#xff0c;执行命令Ifc…

【网管日记】MySQL主从复制

MySQL主从复制 基本介绍 MySQL 主从复制是一个异步的复制过程&#xff0c;底层是基于 Mysql 数据库自带的 二进制日志 功能。 一台或多台 MySQL 数据库&#xff08;slave&#xff0c;即 从库 &#xff09;从另一台 MySQL 数据库&#xff08; master&#xff0c;即 主库 &…

餐饮后台管理系统

一、项目介绍&#xff1a; 用于每天的菜品数据分析&#xff0c;客户的管理&#xff0c;员工的管理&#xff0c;查看订单信息&#xff0c;菜品的添加或者下架管理 二、项目使用技术栈&#xff1a; vue2全家桶、element-ui、axios、js、es6、echarts 三、主页效果图&#xff…

pytorch深度学习实战一书,tensorboard可视化踩坑

书评&踩坑[TOC](书评&踩坑) 提示&#xff1a;纯个人观点&#xff0c;仅供参考前言一、源码学习&#xff0c;又是版本问题&#xff08;省略内心独白...&#xff09;二、步骤1.安装tensorflow2.思考&#xff0c;看代码&#xff0c;看书求证总结提示&#xff1a;纯个人观点…

卧兔CEO胡煜受邀参加2022世界直播电商大会

首届全球数字贸易博览会于12月11日在国际博览中心盛大开幕。在这个国家级、全球性、专业性的舞台上&#xff0c;“2022世界直播电商大会”作为分论坛&#xff0c;精彩启幕。 “2022世界直播电商大会”由浙江省人民政府和商务部联合主办&#xff0c;杭州市人民政府和浙江省商务…

借款久期还款久期 简述

借款久期&还款久期 简述 在工作的时候&#xff0c;在资产使用遇到三个指标&#xff0c;分别是生息资产、借款久期、还款久期&#xff0c;有点不清楚其中的含义&#xff0c;查阅相关资料后做个简短的总结&#xff0c;可能有错&#xff0c;先放这。 1 久期 久期&#xff0…

【STM32】GPIO的工作原理和配置

目录一、GPIO是什么&#xff1f;二、GPIO的8种工作模式1. 浮空输入模式&#xff08;GPIO_Mode_IN_FLOATING&#xff09;2. 上拉输入模式&#xff08;GPIO_Mode_IPU&#xff09;3. 下拉输入模式&#xff08;GPIO_Mode_IPD&#xff09;4. 模拟输入模式&#xff08;GPIO_Mode_AIN&…

kubernetes学习之路--BadPods(Part2)

在我看来&#xff0c;现在关于k8s的攻击面很小&#xff0c;除了容器逃逸&#xff0c;敏感信息和配置不当&#xff0c;很难有其他有效的横向移动的手段了吧&#xff0c;反正据我了解暂时是这样子的&#xff0c;慢慢积累吧还是。 回顾一下Pod中那几项不安全的配置 &#xff1a; …

原地起飞,华为内部都在强推的435页网络协议文档,附讲解

#为什么要学习网络协议&#xff1f; 相信大家都听过通天塔的故事&#xff0c;上帝为了阻止人类联合起来&#xff0c;让人类说不同的语言&#xff0c;人类没法沟通&#xff0c;达不成“协议”&#xff0c;通天塔的计划就失败了。 但是千年以后&#xff0c;有一种叫“程序猿”的…

基于VBA实现电缆结构自动出图(三) —— 多芯线

大家敢相信吗&#xff0c;原来VBA竟然可以实现电缆结构自动出图&#xff0c;换句话说&#xff0c;只要输入数据&#xff0c;VBA会自动将电缆的结构画出来&#xff0c;同时还可以渲染&#xff0c;结果竟然不输画图软件&#xff0c;真真让我刮目相看。这里我就不过多介绍VBA了&am…

重点| 系统集成项目管理工程师考前50个知识点(5)

本文章总结了系统集成项目管理工程师考试背记50个知识点&#xff01;&#xff01;&#xff01; 帮助大家更好的复习&#xff0c;希望能对大家有所帮助 比较长&#xff0c;放了部分&#xff0c;需要可私信&#xff01;&#xff01; 30、活动之间的四种依赖关系&#xff1a; 强…

[附源码]Node.js计算机毕业设计高校互联网班级管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

Redis 压力测试 服务监控

Redis 压力测试 & 服务监控 Redis 压力测试 Redis 安装成功后&#xff0c;会在 /usr/local/bin/目录下生成redis-benchmark压测工具。该工具模拟N个客户端同时执行Redis指令&#xff0c;默认提供一组默认测试参数&#xff0c;用户可以自定义其属性&#xff0c;更改测试行…

java开发必备技能:mysql

mysql 架构 连接器 mysql的连接器负责处理mysql客户端的连接请求及维护连接。 传输协议 mysql支持多种传输协议&#xff0c;不同的平台可以选择不同的协议&#xff1a; 连接压缩控制 mysql建立的连接可以对客户端和服务器之间的流量进行压缩&#xff0c;以减少通过连接发…

Rock派(基于瑞芯微RK3308B)开发记录-上篇

本文作者&#xff1a;Linux兵工厂&#xff0c;一个嵌入式软件领域的攻城狮。欢迎指教公一众-号&#xff1a;Linux兵工厂&#xff0c;获取硬核Linux资料和文章 前言 根据项目需求并且经过各方面评估最终选择了这款Rock Pi(Rock派)系列中的Rock Pi S产品。正式它的各方面的特性…

马士兵-郑金维—并发编程—6.JUC并发工具

JUC并发工具 一、CountDownLatch应用&源码分析 1.1 CountDownLatch介绍 CountDownLatch就是JUC包下的一个工具,整个工具最核心的功能就是计数器。 如果有三个业务需要并行处理,并且需要知道三个业务全部都处理完毕了。 需要一个并发安全的计数器来操作。 CountDown…

Web大学生网页作业成品 :黑色主题个人博客网站设计与实现(HTML+CSS+JavaScript)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

基于java+springmvc+mybatis+vue+mysql的农业信息管理系统

项目介绍 农业信息的需求和管理上的不断提升&#xff0c;农业信息管理的潜力将无限扩大&#xff0c;农业信息管理系统在业界被广泛关注&#xff0c;本系统对此进行总体分析&#xff0c;将农业信息管理的发展提供参考。农业信息管理系统对农业信息有着明显的带动效应&#xff0…

【统一融合:拉普拉斯算子:GAN框架】

UIFGAN: An unsupervised continual-learning generative adversarial network for unified image fusion &#xff08;UIFGAN:一个无监督不断学习生成对抗网络统一的图像融合&#xff09; 本文提出了一种新的无监督连续学习生成对抗网络&#xff08;UIFGAN&#xff09;用于统…