Skip to content

数据库维护与性能

备份与恢复 / 表维护 / 索引优化 / 慢查询 / EXPLAIN

教程最后一篇,讲怎么让你的 MySQL 跑得稳、跑得快。

备份与恢复

mysqldump 备份

最常用的备份工具是 mysqldump——把数据库导出为 SQL 文件:

bash
# 备份单个库
mysqldump -u root -p tutorial > tutorial_backup.sql

# 备份所有库
mysqldump -u root -p --all-databases > all_backup.sql

# 只备份表结构,不要数据
mysqldump -u root -p --no-data tutorial > tutorial_schema.sql

恢复

bash
mysql -u root -p tutorial < tutorial_backup.sql

就是把导出的 SQL 文件重新执行一遍。

🚨 定期备份是最后一道防线。 没有备份 + 误删表 = 灾难。养成定期备份的习惯,尤其是生产环境。

表维护

检查表健康状态

sql
ANALYZE TABLE users;   -- 更新索引统计信息,帮助优化器选对执行计划
CHECK TABLE users;     -- 检查表是否有错误
REPAIR TABLE users;    -- 尝试修复(仅 MyISAM 支持)

ANALYZE TABLE 最常用——执行后优化器能做出更准确的查询计划。数据频繁增删改后建议跑一次。

刷新缓存

sql
FLUSH TABLES;    -- 关闭所有打开的表,刷新缓存

长时间运行后偶尔执行,释放积攒的内存。

索引:查询快的根基

你之前的章节一直看到 PRIMARY KEYFOREIGN KEYFULLTEXT,这些都是索引。

索引就像书的目录——没有目录要翻遍整本书找一句话,有了目录直接翻到对应页。

查看索引

sql
SHOW INDEX FROM users;

创建索引

sql
-- 单列索引
CREATE INDEX idx_city ON users(city);

-- 多列索引(联合索引)
CREATE INDEX idx_city_salary ON users(city, salary);

-- 唯一索引(值不能重复)
CREATE UNIQUE INDEX idx_email ON users(email);

删除索引

sql
DROP INDEX idx_city ON users;

什么时候加索引

  • WHERE 频繁用到的列 → 加索引
  • JOIN 用的外键列 → 加索引
  • ORDER BY 排序的列 → 加索引
  • 数据量小(几千行以下)→ 不用加,全表扫描也不慢

什么时候不加

  • 频繁增删改的列 → 索引维护有代价
  • 值很少的列(如性别只有男/女)→ 索引效果差
  • 很少出现在 WHERE 里的列

💡 不要一上来就疯狂加索引。先跑起来,发现慢了再用 EXPLAIN 定位瓶颈,对症下药。

EXPLAIN:看 SQL 怎么执行

写出 SQL 后,不知道它走没走索引?用 EXPLAIN 看一眼执行计划:

sql
EXPLAIN SELECT * FROM users WHERE city = '北京';
+----+-------------+-------+------+---------------+----------+
| id | select_type | table | type | possible_keys | rows    |
+----+-------------+-------+------+---------------+----------+
|  1 | SIMPLE      | users | ref  | idx_city      | 3        |
+----+-------------+-------+------+---------------+----------+

关键字段:

字段含义好的表现
type访问类型const / eq_ref / ref 最好,ALL 是全表扫描要警惕
possible_keys可能用到的索引有值说明有索引可用
key实际使用的索引NULL 说明没走索引
rows预估扫描行数越小越好
Extra额外信息Using index 最好,Using filesort / Using temporary 需要优化

看到 type = ALLrows 很大?该加索引了。

对比有无索引

sql
-- 没索引:全表扫描
EXPLAIN SELECT * FROM users WHERE name = '张三';
-- type: ALL, rows: 8

-- 加了索引
CREATE INDEX idx_name ON users(name);
EXPLAIN SELECT * FROM users WHERE name = '张三';
-- type: ref, rows: 1

慢查询日志

MySQL 可以记录执行时间超过阈值的 SQL,帮你找出性能瓶颈:

sql
-- 查看慢查询是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 查看阈值(秒)
SHOW VARIABLES LIKE 'long_query_time';

-- 开启慢查询日志
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;   -- 超过 2 秒就记录

日志文件位置:

sql
SHOW VARIABLES LIKE 'slow_query_log_file';

定期翻一翻这个日志,最慢的几条 SQL 就是优化目标。

查询优化速查

几个写 SQL 时的好习惯:

sql
-- ❌ 避免 SELECT *
SELECT * FROM users;

-- ✅ 只查需要的列
SELECT name, city FROM users;

-- ❌ WHERE 里对列做函数运算(会导致不走索引)
SELECT * FROM users WHERE YEAR(created_at) = 2024;

-- ✅ 条件放值这边
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';

-- ❌ 在循环里逐条执行 SQL
-- ✅ 用 INSERT 多行、JOIN、子查询一次性搞定

配置调优(知道有就行)

MySQL 的配置文件 my.cnf 里可以调整内存、连接数等参数:

ini
[mysqld]
innodb_buffer_pool_size = 1G    # InnoDB 缓存池(最重要的参数,建议设为内存的 50%~70%)
max_connections = 200           # 最大连接数
slow_query_log = ON             # 开启慢查询日志
long_query_time = 2             # 慢查询阈值

💡 新手阶段不需要纠结配置——默认参数已经够用了。等你遇到真正的性能瓶颈时再回来调。

日常维护检查清单

每天或每周快速过一遍:

  1. 备份跑了没?mysqldump 定时执行
  2. 慢查询日志有新货吗? — 翻一翻,优化最慢的
  3. 磁盘空间够吗? — 别等到满了才发现
  4. 索引有碎片吗? — 偶尔 ANALYZE TABLE 一下
  5. 有没有人还在用 root 连应用? — 安全审计

小结

教程最后一篇,从"能跑"到"跑得稳、跑得快":

  1. mysqldump 定期备份 — 没有备份 + 误删表 = 灾难,养成定时备份的习惯
  2. 索引是查询快的根基 — WHERE / JOIN / ORDER BY 的列加索引,但不要滥加
  3. EXPLAIN 看执行计划type=ALLrows 很大?该加索引了
  4. 慢查询日志定位瓶颈 — 开启后定期翻一翻,最慢的几条 SQL 就是你该优化的
  5. 日常检查清单 — 备份跑了没?慢查询有新货吗?磁盘够吗?root 还在用吗?

💡 不需要一口气全记住。先跑起来,发现慢了再用 EXPLAIN 定位,对症下药。性能优化是一步一步来的事。

自主练习

  1. 用 mysqldump 备份你的 tutorial
  2. users 表的 name 列加索引,用 EXPLAIN 对比加索引前后查询计划的变化
  3. 查看 MySQL 的慢查询日志是否开启
  4. 用 EXPLAIN 分析一条带 JOIN 的查询,看 key 列是否用到了索引

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8