«

MySQL 慢查询优化实战指南

时间:2026-11-14 07:23     作者:emer     分类: 无


MySQL 慢查询优化实战指南

一、先定位慢在哪

数据库变慢不能靠猜,第一步是打开慢查询日志,把执行时间超过阈值的 SQL 记录下来:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; -- 超过1秒记录
SHOW VARIABLES LIKE 'slow_query_log_file';

再用 EXPLAIN 分析目标 SQL,重点看 type、key、rows、Extra 四列:type 出现 ALL 表示全表扫描,key 为 NULL 说明没走索引,rows 预估扫描行数过大,Extra 出现 Using filesort、Using temporary 都是危险信号。

二、索引优化是核心

1. 给高频查询字段建索引

ALTER TABLE order_table ADD INDEX idx_uid_status (user_id, status);

联合索引遵循最左前缀,查询条件从左到右匹配,跳过中间列后面的列就用不上。

2. 避免索引失效

三、改写低效 SQL

小结果集驱动大表

-- 反例:先扫大表再关联
SELECT * FROM a JOIN b ON a.id = b.a_id WHERE b.type = 1;

-- 优化:先过滤小表,再关联
SELECT a.* FROM (SELECT id FROM b WHERE type = 1 LIMIT 100) t JOIN a ON a.id = t.a_id;

分页深翻页优化

LIMIT 100000, 20 会扫描十万行再丢弃,改用主键游标:

SELECT * FROM order_table WHERE id > 100000 ORDER BY id LIMIT 20;

禁止 SELECT *

只查需要的列,减少回表和网络传输,覆盖索引还能避免回表。

四、表结构与配置优化

  1. 大字段(TEXT、BLOB)拆到副表,主表只存常用字段;
  2. 避免过度索引,索引越多写入越慢,删无用索引;
  3. 合理使用覆盖索引,查询列都在索引里就不用回表;
  4. 调整 buffer_pool_size,一般设为物理内存的 50%~70%;
  5. 慢 SQL 配合业务加缓存,把读压力转移到 Redis。

五、压测与验证

用 EXPLAIN ANALYZE 看真实执行计划,优化前后对比扫描行数和耗时。上线前用慢日志复刻 SQL 在测试库压测,避免只在小表上验证就以为有效。

六、常见误区

  1. 盲目给每个字段加索引,拖慢写入;
  2. 建了联合索引却从非最左列查询,以为没生效;
  3. 只看执行时间不看 EXPLAIN,误判瓶颈;
  4. 深分页一直 LIMIT 偏移量,越翻越慢;
  5. 数据库扛不住就堆硬件,忽略索引和 SQL 本身的问题。

七、总结

慢查询优化链路:开慢日志定位、EXPLAIN 找问题、补索引并避开失效场景、改写 SQL 减小扫描范围、配合表结构和缓存。优化的本质是减少扫描行数和回表次数,先靠定位工具找到真凶,再针对性调整,而不是凭感觉乱建索引。

标签: MySQL 索引优化 Explain 慢查询