MySQL事务与性能优化
一、事务(Transaction)
1.1 什么是事务
事务是一组不可分割的 SQL 操作序列,这些操作要么全部成功执行,要么全部不执行。事务是数据库管理系统执行过程中的一个逻辑单位。
生活中的事务例子:
- 银行转账:A 账户扣款 100 元,B 账户增加 100 元,这两个操作必须同时成功或同时失败
- 电商下单:创建订单、扣减库存、扣款,三个操作必须一起完成
1.2 事务的 ACID 特性
| 特性 | 英文 | 说明 | 示例 |
|---|---|---|---|
| 原子性 | Atomicity | 事务是不可分割的最小单位,要么全部成功,要么全部回滚 | 转账时扣款失败,则收款也不执行 |
| 一致性 | Consistency | 事务执行前后,数据库从一个一致状态变为另一个一致状态 | 转账前后,两人账户总额不变 |
| 隔离性 | Isolation | 多个事务并发执行时,互不干扰 | 事务 A 的修改在提交前,事务 B 看不到 |
| 持久性 | Durability | 事务一旦提交,对数据库的修改永久保存 | 转账成功后,即使系统崩溃,数据也不丢失 |
1 | ┌─────────────────────────────────────────────┐ |
1.3 事务控制语句
1 | -- 开启事务 |
自动提交模式:
1 | -- 查看自动提交状态 |
1.4 事务的隔离级别
多个事务并发执行时,可能出现以下问题:
| 并发问题 | 说明 | 影响 |
|---|---|---|
| 脏读(Dirty Read) | 一个事务读取了另一个事务未提交的数据 | 可能读到最终被回滚的”脏数据” |
| 不可重复读(Non-repeatable Read) | 同一事务内多次读取同一数据,结果不同 | 数据被其他事务修改并提交 |
| 幻读(Phantom Read) | 同一事务内多次查询,结果集行数不同 | 其他事务插入或删除了符合条件的记录 |
| 丢失修改(Lost Update) | 两个事务同时修改同一数据,后提交的事务覆盖前者 | 数据更新丢失 |
| 死锁(Deadlock) | 两个事务相互等待对方释放资源 | 事务无法继续执行 |
四种隔离级别:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 说明 |
|---|---|---|---|---|
| READ UNCOMMITTED | 允许 | 允许 | 允许 | 性能最好,安全性最差 |
| READ COMMITTED | 禁止 | 允许 | 允许 | Oracle 默认 |
| REPEATABLE READ | 禁止 | 禁止 | 允许 | MySQL 默认 |
| SERIALIZABLE | 禁止 | 禁止 | 禁止 | 性能最差,安全性最高 |
1 | -- 查看当前隔离级别 |
各隔离级别详解:
1 | -- ============================================ |
1.5 死锁
死锁产生条件:
- 互斥条件:资源不能被共享
- 请求与保持:持有资源同时请求新资源
- 不剥夺条件:资源只能由持有者释放
- 循环等待:形成等待环路
1 | -- 死锁示例 |
避免死锁的方法:
- 按固定顺序访问资源
- 尽量缩短事务长度
- 使用低隔离级别
- 设置锁等待超时
1 | -- 查看死锁日志 |
1.6 事务实战:银行转账
1 | -- 银行转账完整事务 |
二、SQL 性能优化
2.1 慢查询日志
慢查询日志用于记录执行时间超过阈值的 SQL 语句,是性能优化的重要工具。
1 | -- 查看慢查询日志配置 |
my.cnf / my.ini 配置:
1 | [mysqld] |
分析慢查询日志:
1 | -- 使用 mysqldumpslow 工具分析 |
2.2 EXPLAIN 详解
EXPLAIN 是分析 SQL 执行计划的核心工具。
1 | -- 基本用法 |
EXPLAIN 输出字段详解:
| 字段 | 说明 |
|---|---|
| id | 查询序列号,id 相同从上到下执行,id 不同数值大的先执行 |
| select_type | 查询类型:SIMPLE(简单查询)、PRIMARY(最外层查询)、SUBQUERY(子查询)、DERIVED(派生表)等 |
| table | 当前行操作的表名 |
| partitions | 匹配的分区(未分区则为 NULL) |
| type | 访问类型,性能关键指标 |
| possible_keys | 可能使用的索引 |
| key | 实际使用的索引 |
| key_len | 索引使用的字节数(越短越好) |
| ref | 索引匹配的列或常量 |
| rows | 预估扫描的行数(越小越好) |
| filtered | 查询条件过滤后剩余行的百分比 |
| Extra | 额外信息 |
type 访问类型(性能从优到差):
| type | 说明 | 示例 |
|---|---|---|
| system | 表只有一行 | SELECT * FROM dual |
| const | 主键或唯一索引等值查询 | WHERE id = 1 |
| eq_ref | JOIN 时主键或唯一索引关联 | t1 JOIN t2 ON t1.id = t2.id |
| ref | 普通索引等值查询 | WHERE name = '张三' |
| range | 索引范围查询 | WHERE id BETWEEN 1 AND 100 |
| index | 索引全扫描 | SELECT id FROM table(覆盖索引) |
| ALL | 全表扫描 | SELECT * FROM table |
Extra 常见值:
| Extra 值 | 说明 | 建议 |
|---|---|---|
| Using index | 使用覆盖索引,无需回表 | 优秀 |
| Using where | 使用 WHERE 过滤 | 正常 |
| Using filesort | 需要额外排序 | 优化:为排序字段加索引 |
| Using temporary | 使用临时表 | 优化:简化 GROUP BY / ORDER BY |
| Using join buffer | 使用连接缓存 | 大数据量 JOIN 时正常 |
| Impossible WHERE | WHERE 条件永远为假 | 检查条件逻辑 |
| Select tables optimized away | 优化器确定最多返回一行 | 优秀 |
2.3 EXPLAIN 实战分析
1 | -- 创建测试表 |
1 | -- 案例1:主键等值查询(type = const) |
2.4 慢 SQL 优化方法
优化步骤
1 | 1. 开启慢查询日志,定位慢 SQL |
常见优化方法
1. 添加或优化索引
1 | -- 原查询(全表扫描) |
**2. 避免 SELECT ***
1 | -- ❌ 不推荐 |
3. 优化分页查询
1 | -- ❌ 深分页性能差 |
4. 优化 ORDER BY
1 | -- ❌ Using filesort |
5. 优化子查询
1 | -- ❌ 子查询(效率低) |
6. 优化批量插入
1 | -- ❌ 逐条插入 |
7. 优化大数据量删除
1 | -- ❌ 一次性删除大量数据(锁表时间长) |
2.5 性能优化检查清单
- 是否为 WHERE、JOIN、ORDER BY 字段建立索引
- 是否避免 SELECT *,只查询需要的字段
- 是否避免在索引列上使用函数或运算
- 是否避免 LIKE ‘%xxx’ 左模糊查询
- 是否避免隐式类型转换
- 是否优化深分页查询
- 是否避免大事务长时间运行
- 是否定期 ANALYZE TABLE 更新统计信息
- 是否定期清理无用数据
三、数据库备份与恢复
3.1 备份方式
| 备份方式 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| 物理备份 | 直接复制数据文件 | 速度快,恢复快 | 需要停机或锁表 |
| 逻辑备份 | 导出 SQL 语句 | 灵活,可跨版本 | 速度慢,恢复慢 |
| 全量备份 | 备份全部数据 | 恢复简单 | 占用空间大,耗时长 |
| 增量备份 | 只备份变化的数据 | 节省空间和时间 | 恢复复杂 |
3.2 使用 mysqldump 逻辑备份
1 | # 备份单个数据库 |
mysqldump 常用参数:
| 参数 | 说明 |
|---|---|
-u |
用户名 |
-p |
密码(会提示输入) |
-h |
主机地址 |
-P |
端口号 |
--single-transaction |
对 InnoDB 表进行一致性备份(不锁表) |
--lock-all-tables |
锁定所有表 |
--quick |
逐行读取,大表不缓存到内存 |
--extended-insert |
使用多行 INSERT,加快导入速度 |
--routines |
备份存储过程和函数 |
--triggers |
备份触发器 |
--events |
备份事件 |
3.3 数据恢复
1 | # 恢复整个数据库 |
3.4 使用物理备份(XtraBackup)
1 | # 安装 Percona XtraBackup |
3.5 备份策略建议
1 | ┌─────────────────────────────────────────────┐ |
💡 小结:本章系统介绍了 MySQL 事务与性能优化。事务部分涵盖 ACID 特性、四种隔离级别、并发问题(脏读、不可重复读、幻读)及死锁处理。性能优化部分包括慢查询日志配置、EXPLAIN 执行计划分析、慢 SQL 优化方法(索引优化、分页优化、子查询优化等)。最后介绍了数据库备份与恢复的常用方法(mysqldump、XtraBackup)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Super Bing`s Hexo!

