说说MySQL索引的底层数据结构

MySQL索引的底层数据结构是B+树数据结构

详细介绍一下B+树的数据结构是什么样子的

B+树有三个特性

  1. B+树是一个平衡多叉树,与平衡二叉树的每一个节点下面最多有两个子节点相比B+树每一个节点下面有多个子节点。
  2. B+树叶子节点(也就是最下面一层的没有子节点的节点)有一个双向链表,左右是为了方便范围查找(假如我找前100条数据,那么我找到第一条叶子节点的数据就可以从叶子节点直接向后取100个数据即可,不用再从根节点向下寻找)
  3. B+树的叶子节点有data数据(就是数据库中这一条所有的字段数据),非叶子节点只有索引数据。

那你说一下B树和B+树的区别,为什么MySQL底层使用B+树而不使用B树呢

B树与B+树有两个地方不同,一个是叶子节点的双向链表,一个是B树不是只有叶子节点有data数据,而是所有的节点都有data数据。

那为什么不用二叉树作为索引的底层结构而用B+树呢

因为二叉树的特性造成根节点距离叶子节点的路径太长,假如一个7个节点的数据二叉树从根节点到叶子节点的距离为三。

如果用B+树则距离为1就可以搞定(当然B+树一层不止7个节点,节点数量取决于一页数据能存放多少个节点)

每一个节点都有data数据不是更好吗,不需要到达叶子节点就可以获取数据返回了,为什么B+树还要把其他节点的data数据去掉,只留叶子节点的data数据呢

因为这里涉及到计算机中的IO操作,计算机IO一次只能拿一数据页的数据(姑且认为大小为64KB吧),如果每一个节点都有data数据,那么计算机IO一次可能只够拿一个节点出来,这样,可能IO一百次才能找到结果,如果其他节点不存储data数据,那么这个索引占用空间就少,IO一个可以拿出多个节点来,这样IO的次数就大大降低了,IO一次是比较耗费性能的,所以使用B+树就提高了性能。

那你简单说一下聚集索引和非聚集索引是什么意思

聚集索引:首先所谓聚集的含义是索引与data数据是否相邻,就是我找到索引以后在它附近就可以找到想要的data数据这就是聚集索引。

非聚集索引:非聚集索引就是我找到索引后,在它的附近找不到data数据。

这里我们根据之前的图想一下,之前的图叶子节点下面紧挨着就是data数据,这里肯定是聚集索引啊,那么什么情况下是非聚集索引呢。

在索引的字段是非主键的时候就是非聚集索引。

这里我来举个例子,如果一个student表中有主键id,姓名name,年龄age,住址add。这个时候我们给name字段建立一个索引,给add字段建立了一个索引,那么这个时候是不是有两个B+树的索引结构,那么意味着这两个索引结构的叶子节点都需要有data数据,那岂不是需要将name索引中的data数据复制一份出来给add索引。

那假如有100个字段都建立了索引,岂不是data要复制100遍。能不能只让一个索引的子节点有data数据,其他索引的子节点没有data数据而是放有data数据的索引的地址呢。

这个时候就让哪个索引作为唯一拥有data数据的索引呢,这里很明显可以用主键嘛,因为主键正好是唯一的,其他字段都可以为多个,所以主键所建立的索引就是拥有data数据的聚集索引,而其他非主键字段建立的索引就是非聚集索引。

MySQL语句怎么写可以提高性能呢

当然是建立索引啦,建立了索引犹如给书加上了目录,如鱼得水、如虎添翼

那索引是不是建立的越多越好呢

因为每一个索引就是给索引字段建立一个索引结构,假如现在插入一条数据,那么这条数据也需要将字段建立到索引结构当中,就需要调整索引结构了,如果建立了100个索引,那么插入1条数据需要调整100个索引结构,那么性能就可想而知了。

但是不建立索引又不行,必须还得建立,那么应该怎么建立呢,就是把经常要用到的查询条件的字段建立一个联合索引,这样用一个索引树可以将多个字段建立了索引。

说到了联合索引,如果我建立的联合索引是A、B、C这三个字段,那么我查询的时候条件是A、B那么这个索引还有效果吗?为什么呢?

有效果,因为最左前缀原则,假如当我们给姓名、年龄、性别三个字段建立了索引,那么从左边先开始的字段才可以索引有效果。

那如果我查A和C呢?

那么只有A有索引效果,查询的字段从索引的最左边开始向右查找,如果中间断了,那么后面的索引字段就失去效果了。

讲一下MySQL的索引覆盖是怎么回事吧

所谓索引覆盖就是用索引字段来覆盖要查询的字段。

假如我们要查询两个字段,name和age,我们的sql语句为

select name,age from student where name='张三' and age=20

假如我们这个时候只有name建立了索引,这个时候我们需要在索引中找到name等于张三的这些数据,并回表(就是从普通索引中找不全所要查询的所有字段,那么需要回表再去主键聚簇索引中寻找,因为聚簇索引中有全量的data数据)。

这个时候我们可以看到我们需要查询的字段只有name,age两个字段,这个时候我们可以将name,age这两个字段做一个联合索引,这个时候我们直接通过联合索引就可以找到所要查询出的字段了。

请注意如果是

select name,age,add from student where name=‘张三’ and age=20;

这个时候由于刚刚的联合索引只有name,age两个字段,没有add字段,所以这种情况又要回表查询,这种情况就没有索引覆盖了。

所以我们sql语句要尽可能的查询出少量的字段,就是用哪个字段就查询哪个字段,更要避免select * 的这种情况。

那你再说一下什么是索引下推吧

首先索引下推是MySQL5.6版本引入的一种优化手段,说白了就是优化了一下,具体优化后有了哪些效果呢。关键点:

  1. 第一个字段为非等值字段。

  2. 查询的字段建立了联合索引

前提:

name和age建立了联合索引

例如:

 select name,age from student where name like ‘%李*%’ and age=20;

这个时候如果在5.6之前,我们会在联合索引中先找到所有name为李开头的数据id(主键),然后再去主键索引(聚集索引)中找age为20的数据的id拿回来,然后将最后合并的数据根据id再去聚集索引中找,这样其实是两次回表查询。

而在5.6之后,我们在联合索引中就直接将name为李开头的和age等于20的数据id筛选出来了,然后再去聚集索引中查询,这样就只进行了一次回表查询。

总结:5.6之前如果查询字段为非等值字段,那么后面的查询条件就回去聚集索引中进行判断,5.6之后非等值字段后面的查询条件在当前非聚集索引中也可以进行判断。

那你能说一下索引在什么情况下会失效吗?

1、在使用不等于!= 或者<> 这样的会失效。

2、在使用不包含 not in , 不存在 not exists 这样的会失效。

3、在使用空 is null,不为空 is not null 这样的会失效。

4、在使用小于 <、大于 >、<=、 >= 这些的时候,mysql优化器会根据索引比例、表的数据量大小等因素来决定走不走索引。

那我写了一条sql,我怎么知道这条sql有没有走索引呢

使用explain解释器来查看,在sql语句前面加上explain就可以来查看。

explain中有多列,我们直接看type这一列,这一列表示访问类型,即MySQL决定以哪种形式来查找表中的行,是根据索引还是全表扫描,表示查找数据行记录的大概范围。

type中的数据类型从优到差依次为:

system > const > eq_ref > ref > range > index >ALL

当我们写了一条sql语句发现他的type是ALL的时候我们就要考虑一下怎么优化一下了,因为ALL是最差的,我们就需要琢磨一下怎么优化,当然优化到system是最好的。

数据库有哪些事务隔离级别,MySQL使用了哪种级别呢?

数据库有四种事务隔离级别

读未提交

读已提交

可重复读

可串行化

MySQL默认是可重复读事务隔离级别

那MySQL有哪些锁呢?

从颗粒度来分,MySQL有表锁和行锁。

表锁:每次操作锁住整张表,开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突的概率最低。

行锁:每次操作锁住一行数据。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高。

那你知道MVCC机制吗,他的原理是什么?

MVCC(Multi-Version Concurrency Control)是多版本并发控制,是在多个事务情况下可以保证每个事物之间相互隔离,MVCC机制适用于读已提交和可重复读这两个事务隔离级别。

MVCC机制中有最重要的两部分:

undo日志版本链:在一行数据被多个事务依次修改过后,每次的修改记录都会保存到undo日志版本链中,用于回滚操作。

一致性视图:read-view:每一个事务开启后,执行任何查询sql时就会生成当前事务的一致性视图。这个视图是由查询的时候所有未提交的事务id数组和已创建的最大事务id组成。

总结:MySQL隔离级别是可重复读的,所以当一个事务执行第一个查询语句的时候就生成了一个一致性视图,当第二个事务修改了这条数据够,第一个事务查询的还是原来的数据,因为第一个事务当时查询的时候生成了一致性视图,这个一致性视图对于第一个事务来说没有变化,所以查询出来的数据也没有变化。

Mysql面试大全的更多相关文章

  1. java架构之路-(面试篇)Mysql面试大全

    说一下mysql比较宏观的面试,具体咋写sql的这里就不过多举例了.后面我还会给出一个关于mysql面试优化的试题,这里主要说的索引和B+Tree结构,很少提到我们的集群配置优化方案. 1.索引是什么 ...

  2. PHP面试大全 基础篇100道问题

    2017年3月7日14:23:21 其实计划很久但是移植没时间去收集和处理弄成一个完整的文件 SVN地址: https://git.oschina.net/zxadmin/live_z 目前基础部分更 ...

  3. MySQL 函数大全

    mysql函数大全 对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL,返回NU ...

  4. 常用mysql命令大全

    常用的MySQL命令大全 一.连接MySQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL. 首先在打开DOS窗口,然后进入目录 mysqlbin,再 ...

  5. MYSQL 语法大全自己总结的

    mysql语法大全 --------数据链接---------------------数据库服务启动net start mysql --关闭服务net stop mysql --登录 -u,-p后面不 ...

  6. Mysql 函数大全- 5.6 中文解释函数参考

    mysql 函数大全 5.6 函数参考 5.6函数参考    (只翻译部分,细节查看相关英文版) 12.1功能和操作员参考 12.2表达式评估中的类型转换 12.3运营商 12.4控制流功能 12.5 ...

  7. MySQL 资源大全

    干货!MySQL 资源大全 提交 我的留言 加载中 已留言 shlomi-noach 发起维护的 MySQL 资源列表,内容覆盖:分析工具.备份.性能测试.配置.部署.GUI 等. 伯乐在线已在 Gi ...

  8. MySQL面试总结

    MySQL面试总结 # MySQL的存储引擎 `MyISAM`(默认表类型):非事务的存储引擎,基于传统的`ISAM`(有索引的顺序访问方法)类型,是存储记录和文件的标准方法,不是事务安全,不支持外键 ...

  9. MySQL面试 - 读写分离

    MySQL面试 - 读写分离 面试题 你们有没有做 MySQL 读写分离?如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 ...

  10. [转帖]MySQL的又一神器-锁,MySQL面试必备

    MySQL的又一神器-锁,MySQL面试必备 https://segmentfault.com/a/1190000020762791 lock 低一级的是 latch   原文链接:blog.ouya ...

随机推荐

  1. JVM虚拟机栈

    JVM虚拟机栈 1.概述 1.1背景 由于跨平台性的设计,Java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降 ...

  2. PlayWright(二十二)- allure插件(一)

    在上文中,我们介绍并使用了pytest-html插件,总之并不复杂,但是今天我们要讲一个比pytest-html插件强很多的插件allure报告,我们要掌握他并且灵活使用,之后的框架就不需要考虑其他的 ...

  3. HTML超文本标记语言3

    三.HTML表单标签 1.form标签 <form> form标签 name=表单名称,action=表单提交的地址,method=表单提交方式:get/post get/post详解: ...

  4. 自用 .net C# CSV文件写入读取工具类

    using System.Data; using System.IO; using System.Linq; using System.Text; using System.Text.RegularE ...

  5. 语音合成技术汇总1:Glow-TTS:通过单调对齐实现文本到语音的生成流

    今天开始开一期语音合成经典论文的翻译 Glow-TTS:通过单调对齐实现文本到语音的生成流 摘要: 最近,文本到语音(Text-to-Speech,TTS)模型,如FastSpeech和ParaNet ...

  6. Kitex微服务开发实践(ETCD服务注册)

    服务注册通常用于分布式系统或微服务架构中,是一种用于管理和发现这些分布式服务的机制.它的目标是让服务能够动态地找到其他服务,并能够与其进行通信,而无需显式地配置其位置信息 本文简单讲述使用etcd进行 ...

  7. 手工搭建并配置apache,php,mysql环境服务器

    1,安装apache2.4: 从apache官网中下载windows版本的apache二进制文件,解压 打开apache目录中的bin目录,在其中打开cmd窗口,使用命令: httpd -k inst ...

  8. [ABC129E] Sum Equals Xor

    2023-01-15 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 dp/模拟 解题思路 我们都知道,异或是一种不进位的加法,而要想 $ a ...

  9. ATtiny88初体验(三):串口

    ATtiny88初体验(三):串口 ATtiny88单片机不包含串口模块,因此只能使用软件方式模拟串口时序. 串口通信时序通常由起始位.数据位.校验位和停止位四个部分组成,常见的配置为1位起始位.8位 ...

  10. Programming abstractions in C阅读笔记:p132-p137

    <Programming Abstractions In C>学习第53天,p132-p137,3.2小节"strings"总结如下: 一.技术总结 3.2小节介绍了字 ...