在 RackNerd VPS 上优化 MySQL 慢查询,首选通过开启慢查询日志定位具体 SQL,再使用 EXPLAIN 分析执行计划并补充缺失索引。注意在大表上加索引可能锁表,建议在业务低峰期操作或使用在线 DDL 工具。
先说结论:索引优化是解决 MySQL 慢查询最直接的手段,但需基于实际慢查询日志而非猜测。
- 先定位:开启 slow_query_log 捕获耗时 SQL
- 先做:使用 EXPLAIN 分析 type 字段是否为 ALL
- 再验证:对比优化前后查询耗时及服务器负载
命令速用版
以下命令用于快速检查慢查询状态和分析 SQL 执行计划。
SHOW VARIABLES LIKE 'slow_query_log'; EXPLAIN SELECT * FROM table_name WHERE column = 'value'; ALTER TABLE table_name ADD INDEX idx_column (column);
为什么会这样
慢查询通常是因为 MySQL 执行了全表扫描,导致 CPU 和磁盘 I/O 飙升。
在没有索引的列上进行 WHERE 条件筛选或 JOIN 连接时,数据库需要逐行读取数据。VPS 资源有限,高 I/O 会直接拖慢整个系统。建立索引相当于建立了数据的目录,让 MySQL 能直接跳转到目标数据行,减少扫描范围。
分步处理
按以下顺序操作,确保每一步都有检查点。
1. 开启慢查询日志
编辑 MySQL 配置文件(通常是 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),添加或修改以下配置:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 1
重启 MySQL 服务生效。long_query_time 设为 1 表示记录超过 1 秒的查询。
2. 抓取慢 SQL
运行一段时间后,查看日志文件内容,或使用 mysqldumpslow 工具汇总:
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
找出出现频率高且耗时长的 SQL 语句。
3. 分析执行计划
对抓取的 SQL 前加 EXPLAIN 关键字执行。重点观察 type 和 key 字段。
如果 type 显示为 ALL,表示全表扫描;如果 key 显示为 NULL,表示未使用索引。
4. 创建索引
根据 WHERE 条件列或 JOIN 连接列创建索引。对于大表,使用 ALGORITHM=INPLACE, LOCK=NONE 避免锁表(MySQL 5.6+ 支持):
ALTER TABLE table_name ADD INDEX idx_name (column_name), ALGORITHM=INPLACE, LOCK=NONE;
怎么验证是否生效
再次执行 EXPLAIN 同一条 SQL,确认 type 变为 ref 或 const,key 显示出新建立的索引名。
观察慢查询日志中该类型 SQL 的记录频率是否下降。使用 top 或 htop 命令观察 MySQL 进程的 CPU 和 IO 等待率是否降低。
常见坑
索引并非越多越好,每个索引都会占用磁盘空间并降低写入速度。
在区分度低的列(如性别、状态标志)上建索引通常无效。频繁更新的列不适合建索引。左模糊查询(LIKE '%value')无法使用普通索引。
常见问题
加索引会影响写入性能吗
会。每次 INSERT、UPDATE 或 DELETE 操作都需要同时更新索引树,增加写入开销。
如何判断索引是否被使用
查询 performance_schema 或 sys 库中的 schema_table_statistics 表查看索引读写计数。
VPS 内存小会影响索引效果吗
会。如果索引文件大于可用内存,MySQL 需要频繁从磁盘读取索引页,优化效果会打折。
参考来源
MySQL Official Documentation - Optimization: https://dev.mysql.com/doc/refman/8.0/en/optimization.html
MySQL Official Documentation - EXPLAIN: https://dev.mysql.com/doc/refman/8.0/en/explain.html
MySQL Official Documentation - Slow Query Log: https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html