【Mysql】面试题汇总

1. 存储引擎

1-1. MySQL 支持哪些存储引擎?默认使用哪个?

答:

MySQL 支持的存储引擎包括 InnoDBMyISAMMemory 等。

Mysql 5.5 之前默认的是MyISAM,Mysql 5.5 之后默认的是InnoDB

可以通过 show engines 查看 Mysql 支持的所有存储引擎。

1-2. MySQL 存储引擎架构了解吗?

答:

存储引擎是存储数据建立索引更新/查询数据等技术的实现方式 。

MySQL 的存储引擎设计的是可拔插式的。存储引擎是基于表的,不同的表可以使用不同的存储引擎。

1-3. MyISAM 和 InnoDB 有什么区别?

答:

  • InnoDB 支持事务,MyISAM不支持事务。
  • InnoDB 支持行锁和表锁,MyISAM只支持表锁。
  • InnoDB 支持外键,MyISAM不支持外键。
  • InnoDB 支持MVCC,MyISAM不支持MVCC。
  • InnoDB 支持数据库异常崩溃后的安全恢复,MyISAM不支持。 todo: 原因好像MyISAM没有 undoredo 日志文件

1-4. MyISAM 和 InnoDB 如何选择?

答:

如果对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,InnoDB 存储引擎是比较合适的选择。

对事务的完整性、并发性要求不是很高,以读操作和插入操作为主,MyISAM存储引擎是比较合适的选择。


2. 索引

2-1. 索引是什么,有什么作用?

答:

索引是一种用于快速查询检索数据的数据结构(有序)。

作用:当数据量比较大时,使用索引可以极大地提高数据检索的效率,通过索引项对数据进行排序,降低了数据排序的成本。

2-2. MySQL 中的索引是怎么实现的,为什么选B+树作为索引的数据结构?

答:

MySQL 中默认的存储引擎是 InnoDBInnoDB使用 B+Tree 的数据结构来存储的索引。

B+Tree 是一颗多叉的平衡搜索树,每个节点是可以存储多个值,它是B树的一个变种。

B+Tree 与 B 树的主要区别:

  • B 树每个节点存储数据指针,B+Tree 树非叶子节点只存储指针这样每个非叶子节点存储的指针就会更多,进而树的高度就会更低,进而减少磁盘 I/O 次数。
  • B树的叶子节点没有指针相连, B+Tree 叶子节点形成一个单向链表,更适合范围查询。而Mysql 对B+Tree进行一个优化,多了一个指向相邻节点的指针。这样可以满足字段的降序排序。

B+Tree 与 Hash主要区别:

  • Hash查找的效率很高,但无法做范围查询

综合以上的区别,所以为什么选B+树这种数据结构来实现索引。

2-3. 索引的分类有哪些?

答:

  • 按「数据结构」分类:B+tree索引、Hash索引、全文索引。
  • 按「物理存储」分类:聚簇索引、二级索引。
  • 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引。
  • 按「字段个数」分类:单列索引、联合索引。

在这里插入图片描述

2-4. 什么时候需要 / 不需要索引?

答:

什么时候适用索引?

  • 字段有唯一性限制的,比如商品编码
  • 经常用于 where 查询条件的字段,以及 group byorder by 的字段。因为建立索引之后在 B+Tree 中的记录都是排序好的。

什么时候不适用索引?

  • 查询条件用不到的字段,因为索引是会占用物理空间。
  • 存在大量重复数据的字段。
  • 经常更新的字段不用创建索引,因为索引字段频繁修改,由于要维护 B+Tree的有序性,那么就需要频繁的重建索引。
  • 表数据太少的时候,不需要创建索引。

2-5. 索引什么时候会失效?

答:

  1. 联合索引不满足最左匹配原则
  2. 索引字段使用运算操作
  3. 索引字段使用头部模糊查找
  4. 字符串类型的字段没有加引号,发生了类型转换
  5. 使用or连接条件有一侧的字段没有索引时
  6. 范围查询时,右边的索引会失效

2-6. 什么是最左匹配原则?

答:

比如现在有一个联合索引,它是由多个字段组成的。

此时查询条件的字段一定要包含创建这个联合索引字段时候最左边的那个字段,那么索引才生效。

没有最左边的字段为什么会失效?

因为联合索引首先是按最左边的这个字段进行排序的,如果相同再按之后的字段排序,如果没有第一个字段,那么此时查找的时候,对于其他字段来说就不是有序的了

2-7. 索引的优化方法有哪些?

答:

  • 使用覆盖索引。覆盖索引就是我们要查询的字段,它已经包括在查询条件的联合索引中了。这样就不用回表查询了。
  • 对于一些大字符串的字段,可以建立前缀索引,节省空间。
  • 主键索引最好自增,这样每次插入一条新记录,都是追加操作。如果不是自增,会出现页分裂。

2-8. 表的一行数据大小为1k,有五千万条记录,主键是bigint类型,求B+树的高是多少?

答:

Mysql页中的指针大小固定是6个字节,因为主键是bigint类型,所以是8个字节。一页的大小固定是16k

首先假设一页中有 n 个数据,n + 1 个指针。一页可以存储的总字节 : 16 * 1024 = n * 8 + (n + 1) * 6

求出n后,进而知道了一个页的指针个数。

假设树高为2,则可以存储的总记录数:(n + 1)* (16K / 1K) = (n + 1)* 16

假设树高为3,则可以存储的总记录数:(n + 1)*(n + 1) * 16

假设树高为x,那么将5000万带入上述公式后:5000万 = (n + 1)^ x * 16

从而求出树高x。

2-9. 什么是聚簇索引,什么是二级索引,什么是回表查询?

答:

  • 聚簇索引:B+树的叶子节点保存了整行的数据,聚簇索引有且只能有一个。
  • 二级索引:B+树的叶子节点保存对应的主键,二级索引可以有多个。
  • 回表查询:先通过二级索引找到对应的主键值,然后根据主键值找到聚簇索引中的行数据。

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

2-10. 什么是覆盖索引?

答:

覆盖索引是指:查询的列在一个索引中能够全部找到,从而避免的回表查询。

案例:

id 为主键,为主键索引。name 为普通索引

select * from user where id = 1; # 使用了覆盖索引
select id, name from user where name = 'Aram'; # 使用了覆盖索引
select id, name, gender from user where name = 'Aram'; # 没有使用覆盖索引

3. 锁

3-1. Mysql有哪些锁?

答:

  1. 全局锁:整个数据库就处于只读状态。场景:数据库逻辑备份
  2. 表级锁
    • 表锁
      • 表共享读锁:所有客户端都只能读数据,不能写数据
      • 表独占写锁:只有上锁的客户端可以读写数据,其他都不能读写数据。
    • 元数据锁(MDL)系统自动加 避免DDLCRUD冲突
      • MDL读锁:CRUD操作时,加MDL读锁
      • MDL写锁:对表结构进行变更操作,加MDL写锁
    • 意向锁 系统自动加 快速判断表里的记录是否有行锁,避免行锁表锁冲突
      • 意向共享锁:与 表共享读锁 兼容,与 表独占写锁 互斥
      • 意向排他锁:与 表共享读锁 互斥,与 表独占写锁 互斥
  3. 行级锁 InnoDB 引擎是支持行级锁的,而 MyISAM 引擎并不支持行级锁。
    • 行锁:锁定单个行记录。行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。
      • 共享锁:select … in share mode 会加共享锁,与排他锁互斥
      • 排他锁:insert、update、delete、select … for update 会加排他锁。与共享锁、排他锁互斥
    • 间隙锁:锁定索引之间的间隙,目的解决幻读问题。
    • 临键锁:行锁和间隙锁组合,同时锁住索引项,并锁住索引项前面的间隙

3-2. 什么SQL语句会加行级锁?

答:

update、insert、delete、 select … for update 会加行锁的排他锁

select … in share mode 会加行锁的共享锁

当事务提交了,锁就会被释放

3-3. 行级锁有哪些?

答:

行锁:对索引项加锁

间隙锁:对索引的间隙加锁

临键锁:行锁 + 间隙锁,锁定索引项和索引项前面的间隙

3-4. Mysql是怎么加行级锁的?

答:

加锁的对象是索引项,加锁的基本单位是 next-key lock

next-key lock 在一些场景下会优化成行锁间隙锁

唯一索引进行等值查询的时候

  • 查询记录存在,优化成行锁,确保这个记录不会被删除,防止幻读。
  • 查询记录不存在,在索引树找到第一条大于该查询记录的记录,将该记录的next-key lock优化成间隙锁,确保不会将查询记录插进来,防止幻读。

没有加索引的查询的时候

没有使用索引列作为查询条件,或者查询语句没有走索引查询,导致扫描是全表扫描。那么,每一条记录的索引上都会加 next-key 锁,这样就相当于锁住的全表,这时如果其他事务对该表进行增、删、改操作的时候,都会被阻塞。

因此,在线上在执行 updatedeleteselect ... for update 等具有加锁性质的语句,一定要检查语句是否走了索引,如果是全表扫描的话,会对每一个索引加 next-key 锁,相当于把整个表锁住了

3-5. update条件字段没加索引会锁全表?

答:

会,没有索引会全表扫描,那么,每一条记录的索引上都会加 next-key 锁,这样就相当于锁住的全表。

3-6. 行锁 + 间隙锁可以防止删除操作的幻读吗?

3-7. 加了什么锁会导致死锁?

3-8. 死锁了怎么办?

3-9. 意向锁是什么?有什么作用?它是表级锁还是行级锁?

答:

意向锁是一种表级锁,它是用来避免行锁和表锁发生冲突,可以快速判断表中记录是否有行锁。

当对记录加行锁时,会自动的对表加上意向锁。

3-10. 备份数据库数据的时候,使用全局锁会影响业务,那有什么其他方式可以避免?

答:

InnoDB 存储引擎默认的事务隔离级别是可重复读,那么可以在备份数据库之前先开启事务,会先创建 Read View,然后整个事务执行期间都在用这个 Read View,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。

备份数据库的工具是 mysqldump,在使用 mysqldump 时加上 –single-transaction 参数的时候,就会在备份数据库之前先开启事务。

这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎。

4. 事务

4-1. 事务有哪些特性?

答:

InnoDB 引擎是支持事务的,MyISAM 引擎不支持事务

事务的四大特性:

  • 原子性:事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败
  • 一致性:事务操作的前后,数据库要保持一致性的状态。比如从转账业务角度来看,A向B转账之后,他们账号的总额与转账之前的总额要保持一致
  • 隔离性:数据库是支持多个事务并发执行的,事务不会受到其他并发执行事务的影响
  • 持续性:事务对数据的操作是永久性的,即便系统故障也不会丢失。

4-2. 并发的事务操作会有什么问题?

答:

  • 脏读:一个事务读取了另一个事务未提交的数据。如果另一个事务进行回滚,则当前读取的数据就是脏数据。
  • 不可重复读:在同一个事务内,前后读取同一条数据不一致。
  • 幻读:在一个事务内,前后进行查询时,发现两次读取的记录数量不一样。

4-3. 事务的隔离级别有哪些?

答:

  • 读未提交:一个事务读取另一个事务未提交的数据
  • 读已提交:一个事务读取另一个事务提交的数据
  • 可重复读:在同一个事务内,前后读取同一条数据保持一致
  • 串行化:所有的事务串行执行

4-4. 什么是MVCC?

答:

MVCC全称是多版本并发控制,是数据库中用来实现事务隔离的一种技术,维护了一个数据的多个版本。

MVCC的具体实现,还需要依赖于数据库记录中的隐式字段undo log日志readView

事务id(隐式字段)满足相应的规则(readView中的访问规则)就会读取到对应的版本数据(存放在undo log日志)

4-5. 在可重复读的隔离级别下,是如何解决幻读的?

答:

针对快照读,也就是普通的 select 语句,是通过 MVCC 解决的。因为开启事务后创建的ReadView在后续的数据查询中会一直沿用,所以不会出现幻读的问题

针对当前读,除了快照读(普通select语句)之外的语句,都是当前读,每次执行前都会查询最新的记录,其它也就是select…for update等语句,是通过next-key lock(记录锁+间歇锁)解决的。

比如执行了select * from t_stu where id >2 for update,这个时候就会为id>2的记录加上next-key lock,在本事务提交之前,其它事务都没有办法对id>2的记录进行修改操作,也就解决了幻读问题

4-6. ReadView在MVCC里如何工作?

答:

4-7. Mysql是如何实现可重复读的?

答:

5. 优化

5-1. 在Mysql中如何定位慢查询?

慢查询出现的原因:

  • 聚合查询
  • 多表查询
  • 表数据量过大查询
  • 深度分页查询

表现现象:

  • 页面加载过慢、接口压测响应时间过长(超过1s)

方案一:开源工具

  • 调试工具:Arthas
  • 运维工具:Prometheus、Skywalking

方案二:Mysql自带的慢日志

慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志如果要开启慢查询日志,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:

在这里插入图片描述

配置完毕之后,通过以下指令重新启动MySQL服务器进行测试,查看慢日志文件中记录的信息

var/lib/mysql/localhost-slow.log

在这里插入图片描述

答:

在这里插入图片描述

5-2. 如果有个SQL语句执行很慢,应该如何分析?

答:

慢查询出现的原因:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果 Extra 是 Using index condition 则表明有优化的空间的

  • type:这条sql的连接类型,性能由好到差为 NULL、system、const、eq_ref、ref、range、index、all
  • NULL:查询时没有用到表
  • const:根据主键查询
  • eq_ref:主键索引查询或唯一索引查询
  • ref:索引查询
  • range:范围查询
  • index:全索引树扫描
  • all:全表扫描

最低的要求是:range,如果是 index 或 all 就需要进行优化了。

在这里插入图片描述

答:

在这里插入图片描述

5-3. Mysql超大分页应该如何处理?

答:

当执行 SELECT ... LIMIT N, M 语句时,MySQL实际上会检索前N+M行数据,然后扔掉前N行,返回后面M行。

随着N的增大,MySQL需要检索的数据量和丢弃的数据量也会增大,导致性能问题。

优化思路:分页查询时,通过创建覆盖索引能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。

例如:

select * from user limit 9000000, 10; # 查询9000010条记录,扔掉前9000000行,返回后面10行# 覆盖索引加子查询
select * 
from user u, (select id from user order by id limit 9000000, 10) a 
where u.id = a.id;

原分页查询走的是全表扫描,并且需要返回9000010条的行数据,效率是非常慢的。

而优化后,首先是按顺序分页查询id,此时会使用覆盖索引。查询出id之后,与原表根据id进行连接查询。这样返回的只有是9000010条的id数据,并不是行数据了。

5-4. 索引创建的原则有哪些?

答:

这个情况有很多,不过都有一个大前提,就是表中的数据比较多时,比如要超过10万以上,才会创建索引,并且添加索引的字段是查询比较频繁的字段,一般也是像作为查询条件排序字段分组的字段这些。

通常创建索引的时候都是使用复合索引来创建,一条sql的返回值,尽量使用覆盖索引,如果字段的区分度不高的话,我们也会把它放在组合索引后面的字段。

如果某一个字段的内容较长,我们会考虑使用前缀索引来使用。

当然并不是所有的字段都要添加索引,这个索引的数量也要控制,因为添加索引也会导致新增改的速度变慢。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL Server 文件组详解

数据文件组 SQL Server 数据库最常用的存储文件是数据文件和日志文件。 数据文件用于存储数据,由一个主要数据文件(.mdf)和若干个次要数据文件(.ndf)构成;日志文件用于存储事物日志,由.ldf文件…

创龙教仪基于瑞芯微3568的ARM Cortex A-55教学实验箱 适用于人工智能 传感器 物联网等领域

适用课程 Cortex-A55 ARM嵌入式实验箱主要用于《ARM 系统开发》、《ARM 应用开发》《物联网通信技术》、《嵌入式系统设计》、《移动互联网技术》、《无线传感器网络》、《物联网设计方法与应用》、《人工智能》等课程。 适用专业 Cortex-A55 ARM嵌入式实验箱主要面向电子信…

Java项目:71 ssm基于ssm+vue的外卖点餐系统+vue

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统功能 系统分为前台订餐和后台管理: 1.前台订餐 用户注册、用户登录、我的购物车、我的订单、商品列表 2.后台管理 商品管理&#xf…

Linux:文件读取指令

Linux:文件读取指令 cat指令more指令less指令head指令 & tail指令grep指令 cat指令 cat指令用于查看目标文件的内容。 语法:cat [选项][文件] 比如直接使用cat读取一个文件: 可以看到,其直接在指令的下方,输出了t…

高效的Gitlab Flow最佳实践

文章目录 一、git flow二、github flow三、gitlab flow四、基于gitlab flow的最佳实践1.语义化版本号2.测试发布3.bug修复 参考 业界包含三种flow: Git flowGithub flowGitlab flow 三种工作流程,有一个共同点:都采用"功能驱动式开发&…

7-Zip 23.00 beta以上版本的压缩包兼容性问题

7-Zip 23.00 beta加入了ARM64 filter,7-Zip 24.02 beta加入了RISCV filter,这两个filter不能在之前的版本解压,这两个filter目前只适用于ARM64/RISCV的扩展名是exe/dll的可执行文件,其中ARM64的exe/dll目前比较常见,RI…

kafka2.x版本配置SSL进行加密和身份验证

背景:找了一圈资料,都是东讲讲西讲讲,最后我还没搞好,最终决定参考官网说明。 官网指导手册地址:Apache Kafka 需要预备的知识,keytool和openssl 关于keytool的参考:keytool的使用-CSDN博客 …

Springboot+vue的作业管理系统+数据库+报告+免费远程调试

项目介绍: Springbootvue的作业管理系统,Javaee项目,springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的作业管理系统,采用M(model)V(view)C(controller&…

485问题汇总

485问题汇总 485 通信波形没有负电压 问题描述:设备在没有外设的时候通信波形是正常的,即5V可以出来,在连接上设备后,设备的通信波形的-5V会随着设备的增多,电压会慢慢上升。当设备连接到24台设备后,485总…

蓝桥杯十四届 试题E接龙数列

思路: 做题要想到用对立面解题,要求最短的,就可以先求最长的 //先求最长的接龙序列的长度maxx,再用长度n减去maxx //先声明dp数组,记录以0-9结尾的最长的接龙数列的长度 //以字符串的形式输入 //更新以b结尾的最大接…

linux系统------------MySQL 存储引擎

目录 一、存储引擎概念介绍 二、常用的存储引擎 2.1MyISAM 2.1.1MYlSAM的特点 2.1.2MyISAM 表支持 3 种不同的存储格式⭐: (1)静态(固定长度)表 (2)动态表 (3)压缩表 2.1.3MyISAM适…

使用 Dify 和 AWS Bedrock 玩转 Anthropic Claude 3

本篇文章,聊聊怎么比较稳定的使用 Anthropic Claude 3,以及基于目前表现非常好的模型,来做一些有趣的 AI Native 小工具。 写在前面 在实际体验了半个多月,月初上线的 Anthropic Claude Pro 后,发现 Claude 3 系列模…

学习几个地图组件(基于react)

去年开发时用的公司封装的地图组件,挺方便的,但是拓展性不强,所以看看有哪些优秀的开源地图组件吧 1、React Leaflet 介绍:开源的JavaScript库,用于在web上制作交互式地图,允许你使用React组件的方式在应…

QT作业。。

1.使用手动连接,将登录框中的取消按钮使用t4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数将登录按钮使用t5版本的连接到自定义的槽函数中,在槽函数中判断u界面上输入的账号是否为"admin",密码是否为&q…

Web前端笔记+表单练习+五彩导航

一、笔记 表单&#xff1a;数据交互的一种方式 登录、注册、搜索 <from> <input type""> --- <input type"text"> --- 普通输入框&#xff0c;内容在一行显示 <input type"password"> --- 密码框 <input type"…

内存卡损坏怎么修复数据,内存卡损坏修复数据方法

内存卡损坏是许多用户都可能面临的问题。当我们的内存卡损坏时,其中存储的重要数据可能会受到威胁,承载着我们无尽回忆的数据,一旦失去,将成为大家心中永远的遗憾。因此我们迫切需要找到一种方法来修复这些数据。本文将介绍一些内存卡损坏修复数据方法,帮助大家解决因为内…

【计算机视觉】Gaussian Splatting源码解读补充(一)

本文旨在补充gwpscut创作的博文学习笔记之——3D Gaussian Splatting源码解读。 Gaussian Splatting Github地址&#xff1a;https://github.com/graphdeco-inria/gaussian-splatting 论文地址&#xff1a;https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gauss…

物联网数据报表分析

随着物联网技术的迅猛发展&#xff0c;越来越多的企业开始将物联网解决方案应用于各个领域&#xff0c;从提高生产效率到优化用户体验&#xff0c;物联网都发挥着至关重要的作用。然而&#xff0c;如何有效地分析和管理物联网产生的海量数据&#xff0c;成为企业面临的挑战之一…

Linux centos7安装nginx-1.24.0并且实现自启动

1.安装之前的操作 ps -ef|grep nginx 查看是否有运行 如果有就杀掉 kill -9 pid find / -name nginx 查看nginx文件 rm -rf file /usr/local/nginx* 通通删掉删掉 yum remove nginx 限载一下服务 1.2.下载安装包 地址 nginx: download 2.减压文件 tar…

学习笔记Day14:Linux下软件安装

软件安装 Anaconda 所有语言的包(package)、依赖(dependency)和环境(environment)管理器&#xff0c;类似应用商店 Conda < Miniconda < Anaconda&#xff08;有交互界面&#xff09; Linux下Miniconda即可 安装Miniconda 搜索北外/清华miniconda镜像网站&#xff…