当前位置: 首页 > news >正文

MySQL慢SQL瓶颈定位

一、整体分析思路

遵循「耗时拆分 → 执行计划定位 → 资源/锁/IO排查 → 语句逻辑分析」四步,先分清是扫描多、排序/分组、锁等待、IO高、网络/返回数据量大哪一类瓶颈。

二、第一步:拆分SQL总耗时(区分时间去向)

一条SQL总耗时 =执行耗时 + 锁等待耗时 + IO耗时 + 网络传输耗时
先通过日志/状态判断时间花在哪。

1. 从慢查询日志提取核心指标

慢日志单条记录关键字段:

  • Query_time总执行时间(核心)
  • Lock_time:等待表/行锁的时间
  • Rows_sent:返回给客户端的行数
  • Rows_examined:MySQL实际扫描的行数
  • Rows_read:读取数据行数

快速判断瓶颈类型

  1. Lock_time 占比高→ 瓶颈:锁竞争(并发高、事务长、行锁升级为表锁)
  2. Rows_examined 远大于 Rows_sent→ 瓶颈:无效扫描(索引失效/无索引)
  3. Query_time 高、行数不多、出现 filesort/temporary→ 瓶颈:排序/临时表
  4. Rows_sent 极大→ 瓶颈:返回数据过多、网络传输慢
  5. 磁盘IO飙升、CPU高 → 瓶颈:全表扫描/大量随机IO

三、第二步:EXPLAIN 深度分析执行计划(核心瓶颈定位)

EXPLAIN是定位SQL内部瓶颈的核心,按字段逐一判断问题点,按优先级从高到低排查。

1. 访问类型 type(最关键,代表数据读取方式)

优先级:system > const > eq_ref > ref > range > index > ALL

type 值瓶颈说明严重程度
ALL全表扫描,逐行遍历整张表,CPU+IO双重消耗严重,必须优化
index全索引扫描,比全表扫描略好,但依然遍历整个索引树高,需优化
range范围查询(> < between in like 前缀匹配),范围过大则性能差中等,看扫描范围
ref/eq_ref正常索引命中,无明显瓶颈正常

典型场景type=ALL基本可以确定是缺失索引或索引失效

2. key / possible_keys(索引使用情况)

  • possible_keys:理论可用索引
  • key=NULL未使用任何索引,主瓶颈就是索引问题
  • key有值但type=ALL:索引存在但被SQL逻辑规避,索引失效

3. rows(预估扫描行数)

MySQL预估需要扫描的行数,数值越大,IO/CPU开销越高

  • 单表查询:几十万+行扫描 = 严重瓶颈
  • 多表JOIN:驱动表rows大,会导致后续表循环匹配次数暴增

4. Extra 额外信息(隐藏瓶颈重灾区)

这是排序、分组、临时表、回表等隐性瓶颈的主要来源:

  1. Using filesort

    • 含义:无法利用索引排序,MySQL在内存/磁盘做文件排序
    • 瓶颈:排序消耗CPU+临时IO,数据量越大越慢
    • 触发:ORDER BY字段无索引、排序字段不在联合索引末尾、多字段排序顺序不一致
  2. Using temporary

    • 含义:MySQL创建临时表存放中间结果
    • 瓶颈:临时表涉及内存/磁盘读写,并发下性能暴跌
    • 触发:GROUP BYDISTINCTUNION、子查询、多表聚合无索引
  3. Using index

    • 含义:覆盖索引,无需回表查询数据,性能最优,无瓶颈
  4. Using where

    • 正常:索引过滤后再行条件判断;
    • 异常:配合type=ALL代表全表扫描后逐行过滤,开销极大。
  5. Using join buffer (Block Nested Loop)

    • 含义:JOIN 关联字段无索引,使用连接缓冲区做嵌套循环
    • 瓶颈:多表关联严重低效,属于JOIN索引缺失问题。

5. id & select_type(子查询/关联查询瓶颈)

针对多表、子查询、UNION语句:

  • DERIVED:派生表(子查询生成临时表),高频出现则是瓶颈
  • SUBQUERY:无法优化的子查询,执行多次,叠加耗时
  • 多表id混乱、执行顺序不合理:JOIN 驱动表选择错误(大表驱动小表)

四、第三步:区分四大类典型性能瓶颈+根因分析

结合日志 + Explain,把问题归为4大类,精准定位根因。

类别1:索引类瓶颈(最高发)

现象

  • Explain:type=ALL/indexkey=NULL
  • 慢日志:Rows_examined极大,Lock_time正常

根因

  1. Where/Order by/Group by 字段未建索引
  2. 索引失效:隐式类型转换、索引列运算/函数、like %xxxor跨索引、is not null/not in
  3. 索引区分度太低(低基数索引,如性别、状态),MySQL放弃使用
  4. 联合索引顺序不合理(未遵循最左匹配)

类别2:排序/分组瓶颈(filesort + temporary)

现象

  • Explain:Using filesort/Using temporary
  • 慢日志:扫描行数不多,但 Query_time 偏高

根因

  1. ORDER BY/GROUP BY字段未纳入联合索引
  2. 聚合、去重操作(DISTINCT、UNION)数据量过大
  3. 内存排序空间不足,排序落地到磁盘文件

类别3:锁/事务瓶颈(并发场景高发)

现象

  • 慢日志:Lock_time占总耗时 30% 以上
  • 实时show processlist:大量会话处于Locked状态

根因

  1. 事务执行时间过长,行锁迟迟不释放
  2. 批量更新/删除无索引,行锁升级为表锁
  3. 并发争抢同一行数据,锁等待队列堆积
  4. 死锁(会话互相等待)

类别4:数据量/IO/网络瓶颈

现象1:大结果集返回

  • 慢日志:Rows_sent成千上万行
  • 现象:查询本身很快,但客户端接收数据慢
  • 根因:SELECT *、未分页、一次性返回全量数据,网络传输+客户端解析耗时高

现象2:大分页瓶颈

  • 语句:LIMIT 100000, 10
  • 根因:MySQL需要先扫描前10万行再丢弃,偏移量越大扫描行数越多

现象3:磁盘IO瓶颈

  • 服务器监控:磁盘读IO 100%、CPU 偏高
  • 根因:频繁全表扫描、无覆盖索引导致大量回表查询、临时表/排序落地磁盘

五、第四步:实时状态辅助分析(线上运行中SQL)

适合排查正在执行的慢SQL,补充静态日志的不足。

1. show full processlist

  • 状态Copying to tmp table:正在创建临时表 → 临时表瓶颈
  • 状态Sorting result:正在排序 → filesort 瓶颈
  • 状态Locked:被锁阻塞 → 锁瓶颈
  • 状态Sending data:正在传输结果集 → 网络/返回数据量大

2. 系统状态变量(全局负载)

-- 查看全表扫描次数showglobalstatuslike'Handler_read%';-- 临时表统计(磁盘临时表多=严重瓶颈)showglobalstatuslike'Created_tmp%';-- 文件排序次数showglobalstatuslike'Sort%';
  • Created_tmp_disk_tables持续上涨:大量临时表落地磁盘
  • Sort_merge_passes高:排序内存不足,多次合并排序文件

六、快速分析流程(实战速用)

  1. 看慢日志:对比Lock_time/Rows_examined/Rows_sent,初步划分瓶颈大类
  2. 执行EXPLAIN:优先看typekeyExtra,确认索引、排序、临时表问题
  3. 结合processlist+ 服务器监控:判断是否锁、IO、CPU 资源瓶颈
  4. 回看SQL语法:检查是否分页不当、SELECT *、索引失效写法、不合理子查询/JOIN

七、补充:常见误区

  1. 只看执行时间,不看扫描行数:有些SQL耗时1秒,但扫描百万行,并发后直接雪崩
  2. 有索引就万事大吉:索引失效、联合索引顺序错误依然会慢
  3. 忽略锁等待:并发场景下,锁等待比SQL本身执行更耗时
  4. 轻视临时表/文件排序:数据量上涨后,这两类问题会指数级变慢
http://www.zskr.cn/news/1507911.html

相关文章:

  • 计算机毕业设计之django协同过滤算法的音乐推荐研究
  • 别再死记公式了!用PyTorch的BatchNorm1d/2d跑个Demo,5分钟搞懂它到底在算啥
  • 从RTP包到多协议流:拆解ZLMediaKit中MultiMediaSourceMuxer的‘万能转换’核心
  • 浙江好用的中铁标准抑尘剂生产厂家推荐2026 - 品牌排行榜
  • 深度解析Roboto字体:全面掌握多语言排版与Unicode支持的实用指南
  • ChromePass:当你忘记密码时,你的浏览器记得
  • 给Linux驱动开发者的PCI配置空间Header实战指南:手把手教你读懂BAR、中断与命令寄存器
  • 广州番禺黄金回收哪家好?金小福24小时上门服务口碑佳 - 花生花生1
  • 别再只弹alert了!用XSS_labs靶场实战,手把手教你挖掘Cookie窃取、钓鱼等真实危害
  • 2026深圳App/软件定制公司怎么选?五大维度避坑指南(附 5 家参考名单)
  • 2026年粮仓空调行业深度观察:主流厂商技术路线与选型指南! - 优质品牌商家
  • 如何免费解锁Microsoft 365完整功能:Ohook激活方案完全指南
  • 信奥赛C++提高组csp-s之Dijkstra算法(朴素版)
  • 2026年长城雪茄购买渠道全解析:从成都到香港,哪里买更靠谱? - 优质品牌商家
  • Spring Boot 实现过滤器(Filter)三种常用方式
  • 避开OV5640时钟配置的坑:PCLK计算不准导致图像异常的排查与修复指南
  • 第31篇:AI时代的前端工作流
  • 保姆级教程:用STM32的MPU为你的AUTOSAR应用划清内存“地盘”(附代码)
  • 2026年6月东莞制造业升级,3M VHB GPL160平台选择全攻略 - 品牌鉴赏官2026
  • 北邮网络课设:VC6.0下用select实现的轻量级DNS中继服务源码包
  • 2026年球场护栏网安装厂家怎么选?四川及全国主流服务商综合分析与案例参考 - 优质品牌商家
  • 别再说佳明不准了!手把手教你校准fēnix 7X心率,搞定极限运动数据漂移
  • 如何用foobox三分钟打造专业音乐播放器:foobar2000终极美化指南
  • 3大实战场景!用Buzz离线音频转写工具彻底改变你的音频处理方式
  • Java开发者的效率工具箱:提升编码速度的秘诀
  • DC-DC模块电源的FB引脚,除了调压还能怎么玩?一个运放电路带来的新思路
  • 深入PHY6222蓝牙协议栈:从simpleBLEPeripheral看GATT属性表的组织与交互逻辑
  • 实践:Triton Inference Server 吞吐量优化全解析
  • 告别手动录入:用Java+海康SDK实现明眸门禁人员信息自动同步(Spring Boot项目集成)
  • YTSage YouTube下载器详解