你有没有遇到过这种情况:网页点开半天加载不出来,后台一查,原来是条 SQL 查询卡了快十秒?别急,这多半是慢查询在作怪。尤其在数据量上来之后,一条没写好的语句就能拖垮整个系统。
先定位问题:到底是哪条SQL在拖后腿
在动手优化之前,得先知道谁是罪魁祸首。MySQL 提供了慢查询日志功能,只要设置一个阈值,比如超过2秒的查询都记下来:
SET long_query_time = 2;
SET slow_query_log = ON;
SET slow_query_log_file = '/var/log/mysql/slow.log';
开启后,你就能在日志里看到具体是哪些语句跑得慢,执行时间、扫描行数全都清清楚楚。
给字段加索引,最直接的提速方式
很多慢查询的根源就是缺少索引。比如你经常按用户手机号查订单,但 user_phone 字段上没建索引,那每次就得全表扫描。加个索引,速度可能从几秒降到几十毫秒:
ALTER TABLE orders ADD INDEX idx_user_phone (user_phone);
但注意别乱加,索引也不是越多越好,写入数据时会变慢,占用存储空间。只给常用于查询条件、排序或连接的字段加。
避免 SELECT *,只取需要的字段
有些人图省事,查啥都用 SELECT *,结果一张表几十个字段全捞出来,网络传输和内存消耗都上去了。其实很多时候你只需要 id 和 name:
SELECT id, name FROM users WHERE status = 1;
这样不仅快,还减少数据库压力,特别是大字段比如图片、描述这些。
优化 SQL 写法,避开性能陷阱
有些写法天生就慢。比如在 WHERE 条件里对字段做函数处理:
SELECT * FROM logs WHERE YEAR(create_time) = 2024;
这条语句无法使用 create_time 的索引,得逐行计算年份。改成范围查询就好多了:
SELECT * FROM logs WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01';
分页查询别跳太远
翻到第100页可能还好,但要是 LIMIT 1000000, 20,数据库得先扫前一百万条再扔掉,非常耗资源。这时候可以用记录上次查询位置的方式,比如记住上一页最大的 id,下一页从那里开始:
SELECT * FROM articles WHERE id > 1000000 ORDER BY id LIMIT 20;
效率提升非常明显。
定期分析表结构和执行计划
用 EXPLAIN 看看你的 SQL 到底是怎么执行的。重点关注 type 是否用了 index 或 range,key 是否命中索引,rows 扫了多少行。如果看到 type 是 ALL,基本就是全表扫描了,得想办法优化。
有时候表统计信息不准也会导致执行计划走偏,可以手动更新:
ANALYZE TABLE users;
让优化器更清楚数据分布,选对索引。
慢查询不是什么疑难杂症,大多数时候就是些细节没注意。花点时间看看日志、加加索引、改改语句,系统立马就能轻松不少。别等到用户抱怨卡顿才去查,平时多留心,数据库才能稳稳跑。”}