性能优化与进阶 - MySQL 面试题及答案
2025/12/19大约 5 分钟
返回MySQL 面试题索引 第 4/4 章
25.一条 Sql 语句查询一直慢会是什么原因?

- 「1.没有用到索引」
- 比如函数导致的索引失效,或者本身就没有加索引
- 「2.表数据量太大」
- 考虑分库分表吧
- 「3.优化器选错了索引」
- 「考虑使用」 force index 强制走索引
26.一条 Sql 语句查询偶尔慢会是什么原因?

- 「1. 数据库在刷新脏页」
- 比如 「redolog 写满了」,**「内存不够用了」**释放内存如果是脏页也需要刷,mysql 「正常空闲状态刷脏页」
- 「2. 没有拿到锁」
27.Mysql 主从之间是怎么同步数据的?
- 1.master 主库将此次更新的事件类型**「写入到主库的 binlog 文件」**中
- 2.master 「创建 log dump 线程通知 slave」 需要更新数据
- 3.「slave」 向 master 节点发送请求,「将该 binlog 文件内容存到本地的 relaylog 中」
- 4.「slave 开启 sql 线程」读取 relaylog 中的内容,「将其中的内容在本地重新执行一遍」,完成主从数据同步

「同步策略」:
- 1.「全同步复制」:主库强制同步日志到从库,等全部从库执行完才返回客户端,性能差
- 2.「半同步复制」:主库收到至少一个从库确认就认为操作成功,从库写入日志成功返回ack确认
28.主从延迟要怎么解决?
- 1.MySQL 5.6 版本以后,提供了一种**「并行复制」**的方式,通过将 SQL 线程转换为多个 work 线程来进行重放
- 2.「提高机器配置」(王道)
- 3.在业务初期就选择合适的分库、分表策略,**「避免单表单库过大」**带来额外的复制压力
- 4.「避免长事务」
- 5.「避免让数据库进行各种大量运算」
- 6.对于一些对延迟很敏感的业务**「直接使用主库读」**
29.删除表数据后表的大小却没有变动,这是为什么?
在使用 delete 删除数据时,其实对应的数据行并不是真正的删除,是**「逻辑删除」,InnoDB 仅仅是将其「标记成可复用的状态」**,所以表空间不会变小
30.为什么 VarChar 建议不要超过255?

当定义varchar长度小于等于255时,长度标识位需要一个字节(utf-8编码)
当大于255时,长度标识位需要两个字节,并且建立的**「索引也会失效」**
31.分布式式事务怎么实现?
- 1.「本地消息表」
- 2.「消息事务」
- 3.「二阶段提交」
- 4.「三阶段提交」
- 5.「TCC」
- 6.「最大努力通知」
- 7.「Seata 框架」
32.Mysql 中有哪些锁?
以下并不全,主要理解下锁的意义即可
- 基于锁的属性分类:共享锁、排他锁
- 基于锁的粒度分类:表锁、行锁、记录锁、间隙锁、临键锁
- 基于锁的状态分类:意向共享锁、意向排它锁、死锁
33.为什么不要使用长事务?

- 1.并发情况下,数据库**「连接池容易被撑爆」**
- 2.「容易造成大量的阻塞和锁超时」
- 长事务还占用锁资源,也可能拖垮整个库,
- 3.执行时间长,容易造成**「主从延迟」**
- 4.「回滚所需要的时间比较长」
- 事务越长整个时间段内的事务也就越多
- 5.「undolog 日志越来越大」
- 长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就会导致大量占用存储空间。
34.buffer pool 是做什么的?
buffer pool 是一块内存区域,为了**「提高数据库的性能」**,当数据库操作数据的时候,把硬盘上的数据加载到 buffer pool,不直接和硬盘打交道,操作的是 buffer pool 里面的数据,数据库的增删改查都是在 buffer pool 上进行
buffer pool 里面缓存的数据内容也是一个个数据页
其中**「有三大双向链表」**:
- 「free 链表」
- 用于帮助我们找到空闲的缓存页
- 「flush 链表」
- 用于找到脏缓存页,也就是需要刷盘的缓存页
- 「lru 链表」
- 用来淘汰不常被访问的缓存页,分为热数据区和冷数据区,冷数据区主要存放那些不常被用到的数据
预读机制:
- Buffer Pool 有一项特技叫预读,存储引擎的接口在被 Server 层调用时,会在响应的同时进行预判,将下次可能用到的数据和索引加载到 Buffer Pool
35.说说你的 Sql 调优思路吧

- 1.「表结构优化」
- 1.1拆分字段
- 1.2字段类型的选择
- 1.3字段类型大小的限制
- 1.4合理的增加冗余字段
- 1.5新建字段一定要有默认值
- 2.「索引方面」
- 2.1索引字段的选择
- 2.2利用好mysql支持的索引下推,覆盖索引等功能
- 2.3唯一索引和普通索引的选择
- 3.「查询语句方面」
- 3.1避免索引失效
- 3.2合理的书写where条件字段顺序
- 3.3小表驱动大表
- 3.4可以使用force index()防止优化器选错索引
- 4.「分库分表」
作者:moon聊技术
来源:https://cloud.tencent.com/developer/article/1898311
最近建一些几十个工作内推群,各大城市都有,群里目前已经收集了很多内推岗位,大厂、中厂、小厂、外包都有。 欢迎HR、开发、测试、运维和产品加入。

扫描下方微信,备注:网站+所在城市,即可拉你进工作内推群。
