2024年MySQL数据库面试题整理


学习内容:

1.事务是什么?

事务是⼀组原⼦性的 SQL 查询,或者说⼀个独⽴的⼯作单元。如果数据库引擎能够成功地对数据库应⽤

该组查询的全部语句,那么就执⾏该组查询。如果其中有任何⼀条语句因为崩溃或其他原因⽆法执⾏,

那么所有的语句都不会执⾏。也就是说事务内的语句要么全部执⾏成功,要么全部执⾏失败。

2.事务有什么特性?

原⼦性 atomicity

⼀个事务在逻辑上是必须不可分割的最⼩⼯作单元,整个事务中的所有操作要么全部提交成功,要么全

部失败回滚,对于⼀个事务来说不可能只执⾏其中的⼀部分。

⼀致性 consistency

数据库总是从⼀个⼀致性的状态转换到另⼀个⼀致性的状态。

隔离性 isolation

针对并发事务⽽⾔,隔离性就是要隔离并发运⾏的多个事务之间的相互影响,⼀般来说⼀个事务所做的

修改在最终提交以前,对其他事务是不可⻅的。

持久性 durability

⼀旦事务提交成功,其修改就会永久保存到数据库中,此时即使系统崩溃,修改的数据也不会丢失。

3.MySQL的隔离级别有哪些?

未提交读 READ UNCOMMITTED

在该级别事务中的修改即使没有被提交,对其他事务也是可⻅的。事务可以读取其他事务修改完但未提

交的数据,这种问题称为脏读。这个级别还会导致不可重复读和幻读,性能没有⽐其他级别好很多,很

少使⽤。

提交读 READ COMMITTED

多数数据库系统默认的隔离级别。提交读满⾜了隔离性的简单定义:⼀个事务开始时只能"看⻅"已经提

交的事务所做的修改。换句话说,⼀个事务从开始直到提交之前的任何修改对其他事务都是不可⻅的。

也叫不可重复读,因为两次执⾏同样的查询可能会得到不同结果。

可重复读 REPEATABLE READ(MySQL默认的隔离级别)

可重复读解决了不可重复读的问题,保证了在同⼀个事务中多次读取同样的记录结果⼀致。但还是⽆法

解决幻读,所谓幻读指的是当某个事务在读取某个范围内的记录时,会产⽣幻⾏。InnoDB 存储引擎通

过多版本并发控制MVCC 解决幻读的问题。

可串⾏化 SERIALIZABLE

最⾼的隔离级别,通过强制事务串⾏执⾏,避免幻读。可串⾏化会在读取的每⼀⾏数据上都加锁,可能

导致⼤量的超时和锁争⽤的问题。实际应⽤中很少⽤到这个隔离级别,只有⾮常需要确保数据⼀致性且

可以接受没有并发的情况下才考虑该级别。

4.谈⼀谈 MySQL 的读写锁

在处理并发读或写时,可以通过实现⼀个由两种类型组成的锁系统来解决问题。这两种类型的锁通常被

称为共享锁和排它锁,也叫读锁和写锁。读锁是共享的,相互不阻塞,多个客户在同⼀时刻可以同时读

取同⼀个资源⽽不相互⼲扰。写锁则是排他的,也就是说⼀个写锁会阻塞其他的写锁和读锁,确保在给

定时间内只有⼀个⽤户能执⾏写⼊并防⽌其他⽤户读取正在写⼊的同⼀资源。

在实际的数据库系统中,每时每刻都在发⽣锁定,当某个⽤户在修改某⼀部分数据时,MySQL 会通过

锁定防⽌其他⽤户读取同⼀数据。写锁⽐读锁有更⾼的优先级,⼀个写锁请求可能会被插⼊到读锁队列

的前⾯,但是读锁不能插⼊到写锁前⾯。

5.说一下悲观锁和乐观锁

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到他拿到锁(共享资源每次只给一个线程使用,其他线程阻塞,用完后再把资源转让给其他线程)
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS 算法实现。

6.请说一下 MySQL 支持几种存储引擎?


MySQL支持的引擎主要有以下几种
ISAM:主要用在数据库的查询次数远远大于更新次数的情况下。读写速度快但是不支持事务,也不能容错。如果硬盘崩溃,数据则无法恢复,这是一命的缺点。
MyISAM:MyISAM 是ISAM的扩展格式引擎。它在ISAM 的基础增加了索引和字段管理等大量功能,还具有表格锁定的机制用于优化多个并发的读写操作。 MyISAM 更加强调了数据读取操作,所以在WEB开发中使用非常广泛。 MyISAM 的缺点是不支持事务,且当数据比较多的时候写操作的效率会很低。 InnoDB: InnoDB现在是MySQL默认的数据库引擎,它是一种为巨大数据量而生的最大性能设计,它支持事务,支持多版本读取,而且增加了行级锁机制,此外还支持外键。


7.请说一下 MySQL支持的日志类型有哪些?

错误日志(回滚等):错误日志记录MySQL运行过程中较为严重的警告和错误信息,以及MySQL启动和关闭的详细信息。
二进制日志(主从):包含所有更新数据(新增、删除、修改、改表等)SQL信息的记录。
通用查询日志(记录查询等信息):通用查询日志是记录建立的客户端连接和执行的语句。
慢查询日志:记录所有执行时间超过long_query_time 秒的所有查询或不适用于索引的查询

8.sql的执行流程与数据库的架构

1.客户端向服务器端发送SOL 命令
2.服务器端连接模块连接并验证
3.缓存模块解析SQL 为Hash并与缓存中Hash表对应。如果有结果直接返回结果,如果没有对应继续向下执行
4.解析器解析 SQL 为解析树,如果出现错误,报SQL解析错误。如果正确,向下传递
5.预处理器对解析树继续处理,处理成新的解析树。
6.优化器根据开销自动选择最优执行计划,生成执行计划
7.执行器执行执行计划,访问存储引擎接口
8.存储引擎访问物理文件并返回结果
9.如果开启缓存,缓存管理器把结果放入到查询缓存中。10.返回结果给客户端。
目录    模式    播放

9.数据库死锁如何解决?

死锁是指多个事务在同⼀资源上相互占⽤并请求锁定对⽅占⽤的资源⽽导致恶性循环的现象。当多个事

务试图以不同顺序锁定资源时就可能会产⽣死锁,多个事务同时锁定同⼀个资源时也会产⽣死锁。

为了解决死锁问题,数据库系统实现了各种死锁检测和死锁超时机制。越复杂的系统,例如InnoDB 存

储引擎,越能检测到死锁的循环依赖,并⽴即返回⼀个错误。这种解决⽅式很有效,否则死锁会导致出

现⾮常慢的查询。还有⼀种解决⽅法,就是当查询的时间达到锁等待超时的设定后放弃锁请求,这种⽅

式通常来说不太好。InnoDB ⽬前处理死锁的⽅法是将持有最少⾏级排它锁的事务进⾏回滚。

死锁发⽣之后,只有部分或者完全回滚其中⼀个事务,才能打破死锁。对于事务型系统这是⽆法避免

的,所以应⽤程序在设计时必须考虑如何处理死锁。⼤多数情况下只需要重新执⾏因死锁回滚的事务即

可。

10.索引有什么作⽤?

索引也叫键,是存储引擎⽤于快速找到记录的⼀种数据结构。索引对于良好的性能很关键,尤其是当表

中数据量越来越⼤时,索引对性能的影响愈发重要。在数据量较⼩且负载较低时,不恰当的索引对性能

的影响可能还不明显,但数据量逐渐增⼤时,性能会急剧下降。

索引⼤⼤减少了服务器需要扫描的数据量、可以帮助服务器避免排序和临时表、可以将随机 IO 变成顺

序 IO。但索引并不总是最好的⼯具,对于⾮常⼩的表,⼤部分情况下会采⽤全表扫描。对于中到⼤型的

表,索引就⾮常有效。但对于特⼤型的表,建⽴和使⽤索引的代价也随之增⻓,这种情况下应该使⽤分

区技术。

在MySQL中,⾸先在索引中找到对应的值,然后根据匹配的索引记录找到对应的数据⾏。索引可以包括

⼀个或多个列的值,如果索引包含多个列,那么列的顺序也⼗分重要,因为 MySQL 只能使⽤索引的最

左前缀

11.有哪些优化 SQL 的策略?

优化 COUNT 查询

COUNT 是⼀个特殊的函数,它可以统计某个列值的数量,在统计列值时要求列值是⾮空的,不会统计

NULL 值。如果在 COUNT 中指定了列或列的表达式,则统计的就是这个表达式有值的结果数,⽽不是

NULL。

COUNT 的另⼀个作⽤是统计结果集的⾏数,当 MySQL 确定括号内的表达式不可能为 NULL 时,实际

上就是在统计⾏数。当使⽤ COUNT() 时, 不会扩展成所有列,它会忽略所有的列⽽直接统计所有的

⾏数

某些业务场景并不要求完全精确的 COUNT 值,此时可以使⽤近似值来代替,EXPLAIN 出来的优化器估

算的⾏数就是⼀个不错的近似值,因为执⾏ EXPLAIN 并不需要真正地执⾏查询。

通常来说 COUNT 都需要扫描⼤量的⾏才能获取精确的结果,因此很难优化。在 MySQL 层还能做的就

只有覆盖扫描了,如果还不够就需要修改应⽤的架构,可以增加汇总表或者外部缓存系统。

优化关联查询

确保 ON 或 USING ⼦句中的列上有索引,在创建索引时就要考虑到关联的顺序。

确保任何 GROUP BY 和 ORDER BY 的表达式只涉及到⼀个表中的列,这样 MySQL 才有可能使⽤索引

来优化这个过程。

在 MySQL 5.5 及以下版本尽量避免⼦查询,可以⽤关联查询代替,因为执⾏器会先执⾏外部的 SQL 再

执⾏内部的 SQL。

优化 GROUP BY

如果没有通过 ORDER BY ⼦句显式指定要排序的列,当查询使⽤ GROUP BY 时,结果***⾃动按照分组

的字段进⾏排序,如果不关⼼结果集的顺序,可以使⽤ ORDER BY NULL 禁⽌排序。

优化 LIMIT 分⻚

在偏移量⾮常⼤的时候,需要查询很多条数据再舍弃,这样的代价⾮常⾼。要优化这种查询,要么是在

⻚⾯中限制分⻚的数量,要么是优化⼤偏移量的性能。最简单的办法是尽可能地使⽤覆盖索引扫描,⽽

不是查询所有的列,然后根据需要做⼀次关联操作再返回所需的列。

还有⼀种⽅法是从上⼀次取数据的位置开始扫描,这样就可以避免使⽤ OFFSET。其他优化⽅法还包括

使⽤预先计算的汇总表,或者关联到⼀个冗余表,冗余表只包含主键列和需要做排序的数据列。

优化 UNION 查询

MySQL 通过创建并填充临时表的⽅式来执⾏ UNION 查询,除⾮确实需要服务器消除重复的⾏,否则⼀

定要使⽤ UNION ALL,如果没有 ALL 关键字,MySQL 会给临时表加上 DISTINCT 选项,这会导致对整

个临时表的数据做唯⼀性检查,这样做的代价⾮常⾼。

使⽤⽤户⾃定义变量

在查询中混合使⽤过程化和关系化逻辑的时候,⾃定义变量可能会⾮常有⽤。⽤户⾃定义变量是⼀个⽤

来存储内容的临时容器,在连接 MySQL 的整个过程中都存在,可以在任何可以使⽤表达式的地⽅使⽤

⾃定义变量。例如可以使⽤变量来避免重复查询刚刚更新过的数据、统计更新和插⼊的数量等。

优化 INSERT

需要对⼀张表插⼊很多⾏数据时,应该尽量使⽤⼀次性插⼊多个值的 INSERT 语句,这种⽅式将缩减客

户端与数据库之间的连接、关闭等消耗,效率⽐多条插⼊单个值的 INSERT 语句⾼。也可以关闭事务的

⾃动提交,在插⼊完数据后提交。当插⼊的数据是按主键的顺序插⼊时,效率更⾼。

12.MySQL 主从复制的作⽤?

复制解决的基本问题是让⼀台服务器的数据与其他服务器保持同步,⼀台主库的数据可以同步到多台备

库上,备库本身也可以被配置成另外⼀台服务器的主库。主库和备库之间可以有多种不同的组合⽅式。

MySQL ⽀持两种复制⽅式:基于⾏的复制和基于语句的复制,基于语句的复制也称为逻辑复制,从

MySQL 3.23 版本就已存在,基于⾏的复制⽅式在 5.1 版本才被加进来。这两种⽅式都是通过在主库上

记录⼆进制⽇志、在备库重放⽇志的⽅式来实现异步的数据复制。因此同⼀时刻备库的数据可能与主库

存在不⼀致,并且⽆法包装主备之间的延迟。

MySQL 复制⼤部分是向后兼容的,新版本的服务器可以作为⽼版本服务器的备库,但是⽼版本不能作

为新版本服务器的备库,因为它可能⽆法解析新版本所⽤的新特性或语法,另外所使⽤的⼆进制⽂件格

式也可能不同。

复制解决的问题:数据分布、负载均衡、备份、⾼可⽤性和故障切换、MySQL 升级测试。

13.MySQL 主从复制的步骤?

① 在主库上把数据更改记录到⼆进制⽇志中。 ② 备库将主库的⽇志复制到⾃⼰的中继⽇志中。 ③ 备库

读取中继⽇志中的事件,将其重放到备库数据之上。

第⼀步是在主库上记录⼆进制⽇志,每次准备提交事务完成数据更新前,主库将数据更新的事件记录到

⼆进制⽇志中。MySQL 会按事务提交的顺序⽽⾮每条语句的执⾏顺序来记录⼆进制⽇志,在记录⼆进

制⽇志后,主库会告诉存储引擎可以提交事务了。

下⼀步,备库将主库的⼆进制⽇志复制到其本地的中继⽇志中。备库⾸先会启动⼀个⼯作的 IO 线程,

IO 线程跟主库建⽴⼀个普通的客户端连接,然后在主库上启动⼀个特殊的⼆进制转储线程,这个线程会

读取主库上⼆进制⽇志中的事件。它不会对事件进⾏轮询。如果该线程追赶上了主库将进⼊睡眠状态,

直到主库发送信号量通知其有新的事件产⽣时才会被唤醒,备库 IO 线程会将接收到的事件记录到中继

⽇志中。

备库的 SQL 线程执⾏最后⼀步,该线程从中继⽇志中读取事件并在备库执⾏,从⽽实现备库数据的更

新。当 SQL 线程追赶上 IO 线程时,中继⽇志通常已经在系统缓存中,所以中继⽇志的开销很低。SQL

线程执⾏的时间也可以通过配置选项来决定是否写⼊其⾃⼰的⼆进制⽇志中

  • 25
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值