MySQL 面试高频点通常集中在索引、事务、隔离级别、慢查询和 SQL 优化。本文用后端项目场景讲清这些知识点,不只背概念,而是知道项目里怎么用。

【一、为什么索引很重要】

索引可以理解成书的目录。

没有目录时,要找某一章只能从第一页翻到最后一页;有目录时,可以直接定位。

数据库也是一样。没有索引时,MySQL 可能要全表扫描;有合适索引时,可以快速定位数据。

例如按邮箱查用户:

sql:

SELECT id, username FROM users WHERE email = 'a@test.com';

如果 `email` 没有索引,用户表很大时查询会慢。可以加:

sql:

CREATE UNIQUE INDEX idx_users_email ON users(email);

【二、索引不是越多越好】

索引能加快查询,但会增加写入成本。

因为每次插入、更新、删除数据时,MySQL 不仅要改表数据,还要维护索引结构。

所以索引适合加在:

- 经常用于 WHERE 查询的字段

- 经常用于 JOIN 的字段

- 经常用于 ORDER BY 的字段

- 唯一约束字段,比如 email

- 高区分度字段,比如 user_id、order_no

不适合滥加在:

- 区分度很低的字段,比如 gender、is_deleted

- 很少查询的字段

- 频繁更新且查询很少的字段

【三、联合索引和最左前缀】

联合索引是多个字段一起建立索引。

sql:

CREATE INDEX idx_orders_user_status_created

ON orders(user_id, status, created_at);

这个索引适合:

sql:

WHERE user_id = ?

WHERE user_id = ? AND status = ?

WHERE user_id = ? AND status = ? ORDER BY created_at

但不一定适合:

sql:

WHERE status = ?

因为联合索引遵循最左前缀原则。简单说,索引从左到右生效,跳过左边字段可能用不上。

【四、EXPLAIN 怎么看】

"EXPLAIN” 用来查看 SQL 执行计划。

sql:

EXPLAIN SELECT * FROM orders WHERE user_id = 10;

初学者重点看:

- `type`:访问类型,ALL 通常表示全表扫描。

- `key`:实际使用了哪个索引。

- `rows`:预估扫描多少行。

- `Extra`:是否出现 Using filesort、Using temporary。

如果 `key` 是 NULL,可能说明没有用到索引。

【五、事务是什么】

事务用于保证一组操作要么全部成功,要么全部失败。

比如创建订单:

1. 创建订单

2. 扣减库存

3. 创建支付记录

如果扣库存失败,订单也应该回滚,否则会出现“订单创建了但库存没扣”的脏数据。

SQL 示例:

sql:

START TRANSACTION;

INSERT INTO orders (...);

UPDATE products SET stock = stock - 1 WHERE id = 100 AND stock > 0;

INSERT INTO payment_records (...);

COMMIT;

出错时:

sql:

ROLLBACK;

【六、ACID 怎么理解】

ACID 是事务的四个特性。

- 原子性 Atomicity:一组操作要么全成功,要么全失败。

- 一致性 Consistency:事务前后数据必须满足业务规则。

- 隔离性 Isolation:并发事务之间不能互相乱影响。

- 持久性 Durability:提交后的数据不能丢。

不用背得很玄。记住一句:事务就是为了让多步写入在异常和并发情况下仍然可靠。

【七、隔离级别和常见并发问题】

并发事务可能产生:

- 脏读:读到别人还没提交的数据。

- 不可重复读:同一事务内两次读同一行,结果不一样。

- 幻读:同一事务内两次范围查询,行数不一样。

MySQL InnoDB 默认隔离级别通常是 Repeatable Read。

面试不一定要展开源码,但要能说清:隔离级别越高,并发问题越少,但性能和并发能力可能下降。

【八、常见 SQL 优化思路】

1. 只查需要的字段,避免 `SELECT *`。

2. 给高频查询条件加合适索引。

3. 使用 `EXPLAIN` 分析执行计划。

4. 分页深时避免简单 `LIMIT 100000, 20`。

5. 避免在索引字段上使用函数。

6. 小表驱动大表,注意 JOIN 条件。

7. 批量写入减少多次网络往返。

错误示例:

sql:

SELECT * FROM users WHERE DATE(created_at) = '2026-06-01';

可能导致索引失效。可以改成:

sql:

SELECT id, username

FROM users

WHERE created_at >= '2026-06-01'

  AND created_at < '2026-06-02';

【九、慢查询怎么处理】

项目中遇到慢查询,一般流程:

定位慢 SQL

-> EXPLAIN 看执行计划

-> 判断是否缺索引或索引失效

-> 调整 SQL 或索引

-> 压测或观察线上指标

不要一上来就“加缓存”。缓存是手段,不是逃避 SQL 问题的借口。

更多推荐