一:基础语法与函数(30题)
1. 写出MySQL中插入单条数据、批量数据的SQL语句
INSERT INTO user (id, name, age, create_time) VALUES (1, '张三', 25, NOW());
INSERT INTO 表名 (字段1, 字段2, 字段3, ...)
VALUES
(值1-1, 值1-2, 值1-3, ...),
(值2-1, 值2-2, 值2-3, ...),
(值3-1, 值3-2, 值3-3, ...);
2. delete和truncate的区别是什么?
| 维度 | DELETE | TRUNCATE |
|---|---|---|
| 语法类型 | DML(数据操作语言) | DDL(数据定义语言) |
| 操作性质 | 逐行删除,可带 WHERE 条件 | 清空整张表,无 WHERE 条件(MySQL 8.0+ 支持 TRUNCATE ... WHERE,但极少用) |
| 事务支持 | 可回滚(InnoDB 引擎下,未提交事务时执行 DELETE 可 ROLLBACK) | 不可回滚(执行即生效,DDL 操作会自动提交事务) |
| 自增主键 | 自增主键不会重置,新插入数据从当前最大值继续递增 | 自增主键会重置为初始值(通常是 1) |
| 锁机制 | 行级锁(WHERE 命中索引)或表级锁(无索引 / 全表删除),锁粒度细 | 表级锁,锁定整张表,执行速度快 |
| 触发触发器 | 会触发 DELETE 触发器 | 不会触发任何触发器 |
| 日志记录 | 记录每一行的删除操作(binlog 为行格式时),日志量大 | 仅记录表结构重置,日志量极小 |
| 性能 | 全表删除时速度慢(逐行操作 + 日志) | 全表清空时速度极快(直接重置表) |
| 适用场景 | 删除部分数据(带 WHERE)、需要回滚 / 触发触发器 | 清空整张表、追求极致性能、需重置自增主键 |
| 权限要求 | DELETE 权限 | DROP 权限(比 DELETE 权限更高) |
| 碎片处理 | 仅删除数据,会产生数据碎片 | 会清理数据碎片,释放磁盘空间(等价于重建表) |
3. 如何使用UPDATE语句更新满足多条件的字段值?
UPDATE 表名
SET 字段1 = 新值1, 字段2 = 新值2, ...
WHERE 条件1 [AND/OR] 条件2 [AND/OR] 条件3 ...;
4. INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN的区别是什么?
| 连接类型 | 匹配规则 | 是否保留左表未匹配行 | 是否保留右表未匹配行 | MySQL 支持情况 |
|---|---|---|---|---|
| INNER JOIN | 仅匹配双方都有的行 | ❌ | ❌ | 原生支持 |
| LEFT JOIN | 左表全保留,右表匹配则显示 | ✅ | ❌ | 原生支持 |
| RIGHT JOIN | 右表全保留,左表匹配则显示 | ❌ | ✅ | 原生支持 |
| FULL JOIN | 左右表全保留,无匹配补 NULL | ✅ | ✅ | 需 UNION 模拟 |
5. 子查询和关联查询在性能上有哪些差异?
核心结论先行
- 关联查询(JOIN):MySQL 优化器对 JOIN 的支持更成熟,多数场景下(尤其是多表关联、大数据量)性能更优,执行效率更高;
- 子查询:部分场景(如简单单行子查询)性能接近 JOIN,但嵌套子查询、相关子查询易触发性能问题,甚至导致全表扫描。
一、底层执行逻辑差异(性能的根源)
维度 子查询 关联查询(JOIN) 执行方式 分阶段执行(先查子查询→再查主查询),可能生成临时表 优化器可重排连接顺序、利用索引,多表一次性匹配 临时表 / 文件排序 非相关子查询常生成临时表(DERIVED),消耗内存 / IO 优化得当可避免临时表,直接通过索引关联 索引利用 子查询结果无索引,主查询匹配时可能全表扫描 可直接利用关联字段的索引,减少扫描行数 数据传递 子查询结果集需传递给主查询,数据量大时开销高 多表数据在存储引擎层直接关联,数据传递开销小 二、不同场景的性能对比
1. 简单单行子查询 vs 等值 JOIN(性能接近)
场景:查询单个用户的订单(子查询返回单行值)。
sql
-- 子查询(性能优) SELECT * FROM `order` WHERE user_id = (SELECT id FROM user WHERE name = '张三'); -- JOIN(性能优) SELECT o.* FROM `order` o JOIN user u ON o.user_id = u.id WHERE u.name = '张三';结论:二者性能几乎无差异,MySQL 优化器会将单行子查询转为 JOIN 执行。
2. 非相关子查询(IN 子句)vs JOIN(JOIN 更优)
场景:查询多个用户的订单(子查询返回多行值)。
sql
-- 子查询(性能差:IN 子句结果集大时,无索引,全表匹配) SELECT * FROM `order` WHERE user_id IN (SELECT id FROM user WHERE dept = '技术部'); -- JOIN(性能优:利用 user.id 和 order.user_id 索引) SELECT o.* FROM `order` o JOIN user u ON o.user_id = u.id WHERE u.dept = '技术部';结论:IN 子查询的结果集若超过 1000 行,性能会显著下降;JOIN 可通过索引直接匹配,效率更高。
3. 相关子查询(Correlated Subquery)vs JOIN(JOIN 优势极大)
场景:查询每个用户的最新订单(子查询依赖主查询字段)。
sql
-- 相关子查询(性能极差:主查询每一行都要执行一次子查询,O(n²) 复杂度) SELECT u.name, (SELECT amount FROM `order` o WHERE o.user_id = u.id ORDER BY create_time DESC LIMIT 1) FROM user u; -- JOIN(性能优:通过索引排序+关联,O(n) 复杂度) SELECT u.name, o.amount FROM user u LEFT JOIN ( SELECT user_id, amount, create_time FROM `order` WHERE (user_id, create_time) IN ( SELECT user_id, MAX(create_time) FROM `order` GROUP BY user_id ) ) o ON u.id = o.user_id;结论:相关子查询是「性能陷阱」,主查询有 1000 行则子查询执行 1000 次;JOIN 可通过预聚合 / 索引优化,将复杂度降至线性。
4. 嵌套子查询 vs 多表 JOIN(JOIN 碾压优势)
场景:查询技术部用户的订单,且订单包含某商品。
sql
-- 嵌套子查询(性能极差:多层临时表,无索引) SELECT * FROM `order` WHERE user_id IN ( SELECT id FROM user WHERE dept = (SELECT id FROM dept WHERE name = '技术部') ) AND goods_id = 100; -- 多表 JOIN(性能优:三层 JOIN 利用索引,一次性匹配) SELECT o.* FROM `order` o JOIN user u ON o.user_id = u.id JOIN dept d ON u.dept_id = d.id WHERE d.name = '技术部' AND o.goods_id = 100;结论:嵌套子查询会生成多层临时表,每层都可能全表扫描;多表 JOIN 可通过优化器选择最优连接顺序,利用索引减少扫描。
-
EXISTS和IN的使用场景有何不同?
-
UNION和UNION ALL的区别,使用时需注意什么?
-
如何截取字符串中指定位置的字符(写出至少两种函数)?
-
日期函数NOW()、CURDATE()、CURTIME()的返回值有何不同?
-
如何计算两个日期之间的天数差、月份差?
-
COUNT(*)、COUNT(字段)、COUNT(1)的区别是什么?
-
SUM()函数对NULL值的处理规则是什么?
-
GROUP BY分组后,如何过滤分组结果?
-
HAVING和WHERE的执行顺序及使用区别?
-
DISTINCT的作用,能否与GROUP BY同时使用?
-
如何实现按字段降序排序,相同值按另一字段升序排序?
-
LIMIT子句的语法,offset和rows的含义是什么?
-
如何使用CASE WHEN实现条件分支赋值?
-
如何将多行数据的同一字段值拼接成一个字符串?
-
数值函数ROUND()、CEIL()、FLOOR()的功能分别是什么?
-
如何去除字符串两端的空格?
-
子查询中ANY、ALL、SOME的用法区别?
-
如何使用INSERT ... ON DUPLICATE KEY UPDATE实现重复更新?
-
如何查询表中指定字段的最大值、最小值、平均值?
-
如何使用正则表达式匹配字段中包含特定字符的数据?
-
如何将日期格式从yyyy-mm-dd转换为mm/dd/yyyy?
-
GROUP_CONCAT()函数的默认分隔符是什么,如何修改?
-
如何使用NULLIF()函数处理字段中的特定值?
-
如何查询表中前10%的数据?
-
多表连接时出现笛卡尔积的原因,如何避免?
二、索引(重点维度,40题)
-
索引的定义及作用,为什么索引能提升查询效率?
-
MySQL中索引的分类有哪些(至少列举5种)?
-
主键索引和唯一索引的区别是什么?
-
联合索引的最左前缀原则具体指什么?
-
覆盖索引的定义及使用场景?
-
索引失效的常见场景有哪些(至少列举5种)?
-
如何判断一条SQL语句是否使用了索引?
-
EXPLAIN执行计划中各字段(id、type、key、rows等)的含义?
-
type字段中ALL、range、ref、eq_ref、const的性能排序?
-
聚簇索引和非聚簇索引的区别,InnoDB默认的聚簇索引是什么?
-
为什么InnoDB推荐使用自增主键作为聚簇索引?
-
索引的选择性是什么,如何计算?
-
过多创建索引会带来哪些问题?
-
如何优化低选择性字段的查询效率?
-
前缀索引的适用场景及创建方法?
-
全文索引的使用条件及语法?
-
如何删除无用的索引,删除时需注意什么?
-
索引碎片产生的原因,如何清理?
-
如何查看表中索引的详细信息?
-
联合索引中字段顺序的设计原则是什么?
-
为什么LIKE '%xxx'会导致索引失效,如何优化?
-
函数操作字段、隐式类型转换为何会导致索引失效?
-
OR条件下索引失效的场景,如何优化?
-
索引下推(ICP)的原理及作用?
-
如何设计索引来优化分页查询(如LIMIT 10000,10)?
-
临时表是否会使用索引,如何优化?
-
子查询中索引的使用情况,如何优化?
-
哈希索引和B+树索引的区别及适用场景?
-
如何通过慢查询日志定位索引优化点?
-
索引合并的原理及使用场景?
-
主键索引的叶子节点存储什么,非主键索引的叶子节点存储什么?
-
批量插入数据时,索引对插入性能的影响?
-
如何判断索引是否冗余,举例说明?
-
分区表中索引的设计原则?
-
全文索引与模糊查询的性能对比?
-
索引的创建时机,是建表时还是数据插入后?
-
如何优化联合索引中部分字段为NULL的查询?
-
EXPLAIN中Extra字段为Using filesort、Using temporary的含义及优化方法?
-
读写分离场景下,索引的维护需要注意什么?
-
大表添加索引的优化方法(不锁表)?
三、事务与锁(重点维度,40题)
-
事务的ACID特性分别指什么,如何保证?
-
MySQL的事务隔离级别有哪些,默认是哪个?
-
脏读、不可重复读、幻读的定义及产生场景?
-
不同事务隔离级别能解决哪些并发问题?
-
行锁和表锁的区别及适用场景?
-
间隙锁、临键锁的定义及触发条件?
-
死锁产生的必要条件有哪些?
-
如何排查MySQL中的死锁问题?
-
避免死锁的常用方法有哪些?
-
乐观锁和悲观锁的实现方式及适用场景?
-
InnoDB中行锁的实现原理(基于索引)?
-
为什么更新语句不加索引会导致表锁?
-
事务的提交和回滚原理?
-
长事务的危害及优化方法?
-
如何查看当前数据库的事务隔离级别?
-
如何修改全局/会话级别的事务隔离级别?
-
共享锁(S锁)和排他锁(X锁)的含义及兼容性?
-
意向锁的作用是什么?
-
事务的自动提交(autocommit)机制?
-
保存点(SAVEPOINT)的使用场景及语法?
-
分布式事务的定义及常见解决方案?
-
2PC(两阶段提交)的原理及优缺点?
-
事务隔离级别中可重复读如何解决幻读(Next-Key Lock)?
-
读提交(RC)级别下的MVCC实现原理?
-
锁等待超时参数(innodb_lock_wait_timeout)的作用?
-
如何查看当前数据库的锁等待情况?
-
批量更新数据时,如何减少锁冲突?
-
悲观锁在MySQL中的实现方式(SELECT ... FOR UPDATE)?
-
乐观锁的版本号机制和CAS机制区别?
-
事务的隔离级别与锁的关系?
-
InnoDB的锁升级条件及影响?
-
跨表更新时的锁机制,如何避免死锁?
-
只读事务的优化点?
-
事务日志(redo/undo)与锁的关系?
-
高并发下,如何优化事务的并发性能?
-
幻读和不可重复读的本质区别?
-
如何手动触发死锁,举例说明?
-
全局锁(FLUSH TABLES WITH READ LOCK)的使用场景?
-
元数据锁(MDL)的作用及常见问题?
-
事务的隔离级别设置对性能的影响?
四、存储引擎(重点维度,40题)
-
InnoDB和MyISAM的核心区别(至少列举8点)?
-
InnoDB的架构组成有哪些(至少列举5个组件)?
-
缓冲池(Buffer Pool)的作用及组成?
-
缓冲池的LRU算法原理,如何优化?
-
InnoDB的redo log作用及写入机制?
-
undo log的作用,与redo log的区别?
-
InnoDB的事务实现原理(redo/undo+锁)?
-
MVCC的定义及实现原理(隐藏字段、undo log、read view)?
-
InnoDB的表空间分类(共享/独立/通用)?
-
独立表空间(innodb_file_per_table)的优缺点?
-
MyISAM的索引结构(非聚簇)与InnoDB的区别?
-
InnoDB支持事务,MyISAM不支持,底层原因是什么?
-
InnoDB的崩溃恢复原理(redo log)?
-
存储引擎的选择依据是什么?
-
Memory存储引擎的特点及适用场景?
-
Archive存储引擎的特点?
-
InnoDB的锁机制与存储引擎的关系?
-
MyISAM的表锁粒度及并发问题?
-
InnoDB的页大小默认是多少,能否修改?
-
页分裂的原因及对性能的影响?
-
InnoDB的自适应哈希索引(AHI)原理及作用?
-
InnoDB的双写缓冲区(doublewrite buffer)作用?
-
MyISAM的崩溃恢复机制(chkMyISAM)?
-
InnoDB的事务隔离级别与MVCC的关系?
-
如何查看表的存储引擎类型?
-
如何修改表的存储引擎?
-
InnoDB的行格式(Compact/Dynamic/Compressed)区别?
-
大字段(BLOB/TEXT)在不同存储引擎中的存储方式?
-
InnoDB的预读(read ahead)机制?
-
MyISAM的键缓存(key buffer)作用?
-
InnoDB的刷新策略(innodb_flush_log_at_trx_commit)?
-
存储引擎对索引的支持差异(如全文索引)?
-
InnoDB的外键约束实现原理,MyISAM是否支持?
-
分区表在不同存储引擎中的支持情况?
-
InnoDB的线程池机制?
-
MyISAM的并发插入(concurrent insert)机制?
-
InnoDB的脏页刷新机制?
-
存储引擎对锁的支持差异(行锁/表锁)?
-
InnoDB的redo log文件大小及数量配置原则?
-
不同存储引擎的备份策略差异?
五、日志体系(30题)
-
redo log、undo log、binlog的作用分别是什么?
-
redo log的物理日志特性具体指什么?
-
binlog的逻辑日志特性具体指什么?
-
redo log的写入流程(prepare/commit阶段)?
-
两阶段提交的原理,为什么需要两阶段提交?
-
binlog的格式有哪些(ROW/STATEMENT/MIXED),区别是什么?
-
如何开启binlog,查看binlog的配置参数?
-
redo log的循环写机制,文件满了会发生什么?
-
undo log的生命周期,事务提交后是否立即删除?
-
binlog的刷盘机制(sync_binlog参数)?
-
如何查看binlog中的内容?
-
如何通过binlog恢复数据?
-
redo log和binlog的同步时机?
-
慢查询日志的开启方法及配置参数?
-
错误日志的作用,如何查看错误日志位置?
-
通用查询日志的作用及开启注意事项?
-
中继日志(relay log)的作用,主从复制中如何使用?
-
binlog的过期清理策略(expire_logs_days)?
-
redo log buffer的作用,何时刷入磁盘?
-
undo log的版本链与MVCC的关系?
-
不同binlog格式对主从复制的影响?
-
如何定位binlog中指定时间/SQL的位置?
-
redo log的checkpoint机制原理?
-
binlog的event类型有哪些(至少列举5种)?
-
日志文件过大对性能的影响,如何优化?
-
主从复制中binlog和relay log的关系?
-
如何关闭binlog(临时/永久)?
-
undo log的表空间管理(共享/独立)?
-
慢查询日志中long_query_time参数的作用,默认值是多少?
-
日志刷盘策略对数据库性能和数据一致性的影响?
六、性能优化(重点维度,40题)
-
慢查询的定位方法(至少列举3种)?
-
优化SQL语句的常用步骤?
-
避免全表扫描的常用方法?
-
表结构优化的基本原则(至少列举5点)?
-
字段类型选择的优化原则(如字符型选CHAR/VARCHAR)?
-
范式和反范式的适用场景?
-
大表拆分的常用方法(垂直/水平)?
-
大批量插入数据的优化方法(至少列举5种)?
-
MySQL配置优化的核心参数(至少列举8个)?
-
连接数参数(max_connections)的设置原则?
-
缓冲池(innodb_buffer_pool_size)的配置建议?
-
如何优化分页查询(LIMIT偏移量大的场景)?
-
子查询优化为关联查询的场景及方法?
-
如何优化GROUP BY和ORDER BY语句?
-
临时表的优化方法?
-
视图的性能影响及优化?
-
索引优化的核心原则(至少列举5点)?
-
如何优化JOIN语句(减少笛卡尔积、小表驱动大表)?
-
大表DDL操作的优化方法(如在线DDL)?
-
碎片整理的方法(OPTIMIZE TABLE)?
-
读写分离的实现方式及性能优化点?
-
缓存(如Redis)与MySQL结合的优化策略?
-
如何优化COUNT(*)的查询性能?
-
高并发下INSERT的优化方法(如批量插入、禁用索引)?
-
分区表的性能优化场景及配置?
-
如何优化锁等待导致的性能问题?
-
磁盘I/O的优化方法(如RAID、SSD)?
-
MySQL的查询缓存(query_cache)的适用场景?
-
如何优化分布式事务的性能?
-
长连接的优化方法(避免连接数耗尽)?
-
排序操作的优化(Using filesort)?
-
如何监控MySQL的性能指标(如CPU、内存、IO)?
-
表字段冗余设计的优化场景?
-
批量更新的优化方法(如CASE WHEN、批量提交)?
-
字符集和校对规则的选择对性能的影响?
-
如何优化存储过程/函数的性能?
-
主从延迟的性能影响及优化?
-
大字段(BLOB/TEXT)的存储优化?
-
数据库连接池的配置优化(如最大空闲数、最大连接数)?
-
性能优化的评估方法(如何验证优化效果)?
七、主从复制与高可用(30题)
-
MySQL主从复制的基本原理(3个线程)?
-
主从复制的搭建步骤(简要)?
-
异步复制、半同步复制的区别?
-
主从复制的模式(基于语句/基于行/混合)?
-
主从延迟的常见原因(至少列举5种)?
-
解决主从延迟的常用方法?
-
主从复制中binlog的作用?
-
中继日志(relay log)损坏后的恢复方法?
-
主库宕机后,如何切换到从库?
-
从库的只读模式(read_only)配置?
-
主从复制中权限配置的注意事项?
-
如何检查主从复制的状态?
-
主从复制中数据不一致的排查方法?
-
主从复制的过滤规则(复制指定库/表)?
-
级联复制(主→从→从)的配置要点?
-
MGR(MySQL Group Replication)的原理及优势?
-
MHA(Master High Availability)的工作原理?
-
哨兵(Sentinel)在MySQL高可用中的作用?
-
主从复制中GTID的作用及开启方法?
-
GTID复制与传统复制的区别?
-
从库提升为主库后,其他从库如何重新同步?
-
主从复制中网络延迟的优化方法?
-
主库binlog清理对从库的影响?
-
半同步复制的超时参数(rpl_semi_sync_master_timeout)?
-
主从复制中索引不一致的影响?
-
读写分离中,写操作如何保证主从一致性?
-
高可用架构中,脑裂问题的解决方法?
-
主从复制的监控指标(至少列举5个)?
-
跨机房主从复制的优化方法?
-
主从复制故障的自动恢复方案?
八、架构与分布式(30题)
-
分库分表的适用场景?
-
垂直分库、垂直分表的区别及适用场景?
-
水平分表的分片规则(至少列举3种)?
-
分库分表后,如何解决分布式事务问题?
-
分布式ID的生成方案(至少列举4种)?
-
雪花算法的原理及优缺点?
-
分库分表中间件(Sharding-JDBC/MyCat)的区别?
-
读写分离的架构设计(主库写、从库读)?
-
缓存穿透的解决方案?
-
缓存击穿的解决方案?
-
缓存雪崩的解决方案?
-
分布式锁的实现方式(基于MySQL/Redis/ZK)?
-
2PC、TCC、SAGA、本地消息表的适用场景?
-
分库分表后,分页查询的难点及解决方法?
-
分库分表后,排序、分组的实现方式?
-
数据分片后的扩容方法(如平滑扩容)?
-
异地多活架构的设计要点?
-
分布式系统中的CAP理论,MySQL如何选择?
-
BASE理论的含义及与ACID的区别?
-
分库分表后,全局表的作用?
-
数据一致性校验的方法(分库分表后)?
-
分布式事务中的最终一致性实现方案?
-
读写分离中,从库延迟导致的数据不一致问题?
-
微服务架构中,MySQL的部署方式?
-
分库分表后,索引的设计原则?
-
数据分片的粒度选择(按用户ID/时间)?
-
分布式系统中,数据库连接池的配置?
-
分库分表后,事务回滚的难点?
-
多数据源的管理方法(如Dynamic-Datasource)?
-
分布式架构下,MySQL的备份与恢复策略?
总结
-
重点维度(索引、事务与锁、存储引擎、性能优化)各40题,覆盖核心原理、使用场景、问题排查与优化;
-
基础维度(基础语法、日志、主从复制、架构分布式)各30题,聚焦基础概念、流程、配置与核心问题;
-
所有题目从面试高频考点出发,覆盖MySQL从基础到架构的全维度考察点,兼具广度与深度。