数据库维护与性能
备份与恢复 / 表维护 / 索引优化 / 慢查询 / 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 KEY、FOREIGN KEY、FULLTEXT,这些都是索引。
索引就像书的目录——没有目录要翻遍整本书找一句话,有了目录直接翻到对应页。
查看索引
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 = ALL 且 rows 很大?该加索引了。
对比有无索引
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 # 慢查询阈值💡 新手阶段不需要纠结配置——默认参数已经够用了。等你遇到真正的性能瓶颈时再回来调。
日常维护检查清单
每天或每周快速过一遍:
- 备份跑了没? —
mysqldump定时执行 - 慢查询日志有新货吗? — 翻一翻,优化最慢的
- 磁盘空间够吗? — 别等到满了才发现
- 索引有碎片吗? — 偶尔
ANALYZE TABLE一下 - 有没有人还在用 root 连应用? — 安全审计
小结
教程最后一篇,从"能跑"到"跑得稳、跑得快":
mysqldump定期备份 — 没有备份 + 误删表 = 灾难,养成定时备份的习惯- 索引是查询快的根基 — WHERE / JOIN / ORDER BY 的列加索引,但不要滥加
EXPLAIN看执行计划 —type=ALL且rows很大?该加索引了- 慢查询日志定位瓶颈 — 开启后定期翻一翻,最慢的几条 SQL 就是你该优化的
- 日常检查清单 — 备份跑了没?慢查询有新货吗?磁盘够吗?root 还在用吗?
💡 不需要一口气全记住。先跑起来,发现慢了再用 EXPLAIN 定位,对症下药。性能优化是一步一步来的事。
自主练习
- 用 mysqldump 备份你的
tutorial库 - 给
users表的name列加索引,用 EXPLAIN 对比加索引前后查询计划的变化 - 查看 MySQL 的慢查询日志是否开启
- 用 EXPLAIN 分析一条带 JOIN 的查询,看 key 列是否用到了索引