MySQL慢查询排查:执行计划与索引优化方法
定位慢查询:确认问题 SQL 与性能瓶颈
定位慢查询是优化的第一步,切忌盲目加索引。首先需开启慢查询日志,通过执行 `SET GLOBAL slow_query_log = ON;` 与 `SET GLOBAL long_query_time = 1;` 记录执行超时的 SQL。结合 `mysqldumpslow` 或 `pt-query-digest` 工具可快速聚合高频慢 SQL 并提取完整参数。定位时需严格区分性能瓶颈来源:若 `Lock_time` 远大于 `Query_time`,说明是行锁或表锁等待而非引擎执行慢;若数据库返回极快但应用层响应延迟,通常是网络抖动或代码序列化耗时。借助 Performance Schema 的 `events_statements_history` 表或 Prometheus+Grafana 监控面板,可直观对比 `Rows_examined` 与 `Rows_sent` 比例。只有明确是数据库层面的扫描或计算瓶颈,才进入后续执行计划分析阶段。

看懂 EXPLAIN:从执行计划判断索引是否有效
`EXPLAIN` 是解读 SQL 执行计划的核心工具。执行 `EXPLAIN SELECT ...` 后,需重点关注 `type`、`key`、`rows` 与 `Extra` 字段。`type` 反映访问类型,从优到劣依次为 system、const、eq_ref、ref、range、index、ALL,出现 `ALL` 即代表全表扫描。`key` 显示优化器实际选用的索引,若为 NULL 则未命中。`rows` 为预估扫描行数,数值过大通常意味着索引失效或统计信息陈旧。`Extra` 包含关键诊断信号:`Using filesort` 表示无法利用索引完成排序,需额外内存或磁盘排序;`Using temporary` 说明使用了临时表处理 GROUP BY 或 DISTINCT,极易引发 IO 瓶颈。结合 `filtered` 字段可评估索引过滤效率,若 `rows * filtered` 仍接近全表数据量,则当前索引设计存在明显缺陷。

索引优化:围绕查询条件设计合适索引
索引设计必须紧密贴合查询模式。单列索引适用于独立等值查询或排序场景,而联合索引需严格遵循“最左前缀匹配原则”。例如索引 `(status, create_time, user_id)`,查询条件必须包含 `status` 才能生效,若仅查 `create_time` 则索引失效。设计时应将等值匹配列置于最左,范围查询列居中,排序/分组列靠右,以最大化利用索引树。当查询所需字段全部包含在索引中时,会触发覆盖索引(`Extra` 显示 `Using index`),彻底避免回表开销。同时,需定期通过 `SHOW INDEX FROM table_name` 审查冗余索引,如已存在 `(a, b)` 则无需单独创建 `(a)`。避免为低频查询或高并发写入表盲目堆砌索引,以免拖慢 INSERT/UPDATE 性能。
优化后验证:对比执行计划与实际耗时
优化效果绝不能仅凭 `EXPLAIN` 的理论预估下定论,必须结合真实运行数据验证。MySQL 8.0 引入的 `EXPLAIN ANALYZE` 可直接输出各执行节点的实际耗时与真实行数,精准定位耗时瓶颈。对于旧版本,可开启 `SET profiling = 1;` 执行查询后通过 `SHOW PROFILES;` 查看精确耗时。验证时需对比优化前后的核心指标:`Rows_examined` 是否显著下降、`duration` 是否缩短、CPU 与 IO 使用率是否回落。若执行计划显示 `type` 从 `ALL` 变为 `ref` 或 `range`,且实际耗时降低 50% 以上,方可确认优化有效。建议在预发环境使用生产脱敏数据压测,避免 Buffer Pool 缓存干扰,确保优化方案在真实负载下具备稳定性与可复用性。

常见避坑:索引不是越多越好
索引滥用是性能恶化的常见诱因。隐式类型转换会导致索引失效,如 `WHERE phone = 13800000000`(phone 为 VARCHAR)会触发隐式转换并走全表扫描;对索引列使用函数(如 `WHERE YEAR(create_time)=2023`)或前导模糊匹配(`LIKE '%abc'`)同样会破坏索引结构。低选择性字段(如性别、状态枚举)建立索引收益极低,反而增加 B+ 树维护成本。联合索引顺序颠倒(将范围查询列放最左)会阻断后续列的匹配。此外,`SELECT *` 会破坏覆盖索引,强制回表;统计信息过期会导致优化器选错索引,需定期执行 `ANALYZE TABLE` 刷新。当表数据量极小(如不足千行)或写入远大于读取时,全表扫描往往比索引查找更快,此时不应强行加索引。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













