数据库查询太慢怎么办?
用户反馈页面加载慢,一查发现是数据库查询拖后腿。这种情况太常见了。
今天聊聊怎么定位和优化MySQL慢查询,不讲太深的理论,就说实用的。
怎么发现慢查询?
首先得知道哪些SQL慢。MySQL有个慢查询日志功能,开启后会自动记录执行时间超过阈值的SQL。
查看当前配置:
SHOW VARIABLES LIKE 'slow_query_log';SHOW VARIABLES LIKE 'long_query_time';临时开启:
SET GLOBAL slow_query_log = 'ON';SET GLOBAL long_query_time = 1; -- 超过1秒就记录开启后,执行慢的SQL都会被记录到日志文件里。
找到慢SQL后怎么分析?
用EXPLAIN命令,它能告诉你这条SQL是怎么执行的。
EXPLAIN SELECT * FROM orders WHERE user_id = 123;执行后会显示一堆信息,重点看这几个:
type字段 - 访问类型,越往左越好
system > const > eq_ref > ref > range > index > ALL如果看到ALL,说明在全表扫描,这是最慢的,需要优化。
key字段 - 实际用的索引
如果是NULL,说明没用上索引,这通常就是慢的原因。
rows字段 - 预估扫描行数
这个数字越大,查询越慢。
最常见的优化方法
1. 加索引
90%的慢查询都是因为没索引。
-- 给user_id加索引ALTER TABLE orders ADD INDEX idx_user_id (user_id);加完后再EXPLAIN看看,type应该从ALL变成ref或range了。
**2. 避免SELECT ***
-- 差:查所有字段SELECT * FROM users WHERE id = 1;-- 好:只查需要的SELECT id, name, email FROM users WHERE id = 1;字段少了,传输数据量小,自然快。
3. 注意索引失效的情况
有些写法会导致索引用不上:
-- 对字段用函数,索引失效SELECT * FROM users WHERE YEAR(created_at) = 2024;-- 正确写法SELECT * FROM users WHERE created_at >= '2024-01-01';-- LIKE以%开头,索引失效SELECT * FROM users WHERE name LIKE '%张';-- 这样可以用索引SELECT * FROM users WHERE name LIKE '张%';-- 类型不匹配,索引失效SELECT * FROM users WHERE phone = 13800138000; -- phone是varchar-- 正确写法SELECT * FROM users WHERE phone = '13800138000';4. 分页优化
深分页特别慢:
-- 慢:需要扫描前100万条SELECT * FROM logs ORDER BY id LIMIT 1000000, 20;-- 快:用ID定位SELECT * FROM logs WHERE id > 1000000 ORDER BY id LIMIT 20;联合索引的坑
假设建了一个联合索引 (a, b, c),使用时要注意顺序:
-- 用得上索引SELECT * FROM t WHERE a = 1;SELECT * FROM t WHERE a = 1 AND b = 2;SELECT * FROM t WHERE a = 1 AND b = 2 AND c = 3;-- 用不上索引!SELECT * FROM t WHERE b = 2; -- 没有aSELECT * FROM t WHERE b = 2 AND c = 3; -- 没有a记住"最左前缀"原则:必须从最左边的字段开始用。
实战案例
问题SQL:
SELECT * FROM orders WHERE status = 'pending' ORDER BY create_time DESC;-- 执行时间:5秒分析:
EXPLAIN SELECT * FROM orders WHERE status = 'pending' ORDER BY create_time DESC;-- type: ALL(全表扫描)-- Extra: Using filesort(额外排序)优化:加联合索引
ALTER TABLE orders ADD INDEX idx_status_time (status, create_time);效果:
-- type: ref-- Extra: Using index condition-- 执行时间:0.05秒从5秒优化到0.05秒,快了100倍。
几个实用技巧
1. 定期查看慢查询
-- 查看正在执行的SQLSHOW PROCESSLIST;-- 杀掉太慢的查询KILL 查询ID;2. 查看表索引

SHOW INDEX FROM 表名;3. 分析表统计信息
ANALYZE TABLE 表名;小结
MySQL优化核心思路:
- 开启慢查询日志,找到慢SQL
- 用EXPLAIN分析执行计划
- 根据情况加索引、改写法
- 验证优化效果
大部分性能问题都是索引问题,先把索引搞明白,能解决80%的慢查询。
顺便说一下,我经常需要远程连公司的测试数据库分析慢查询。以前用公司VPN老是断,后来用星空组网把笔记本和公司网络连起来,在家也能直接连内网的MySQL,EXPLAIN调试方便多了。
有问题欢迎交流~
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有