OceanBase 慢 SQL 诊断
何时使用
用户提供以下任意组合时使用:
- 一条执行慢的 SQL(SELECT / UPDATE / DELETE)
EXPLAIN或EXPLAIN FORMAT=JSON的输出- 表结构(
SHOW CREATE TABLE) - 现象描述(慢在哪个环节、并发量、数据量级)
缺少执行计划时,先向用户索取;不要凭 SQL 文本猜测执行路径。
诊断流程
第一步:确认事实,不做假设
从材料里提取:
| 项 | 来源 | 缺失时 |
|---|---|---|
| 表行数 | SHOW TABLE STATUS / 用户描述 | 标“未知”,并在结论里标注不确定性 |
| 访问方式 | 执行计划的 type / access_type | 必须取得 |
| 扫描行数 | rows / estimated_rows | 必须取得 |
| 是否回表 | Extra 是否含 Using index | 必须取得 |
| 排序/临时表 | Using filesort / Using temporary | 必须取得 |
| 索引情况 | SHOW CREATE TABLE | 建议前必须确认 |
第二步:定位瓶颈(按优先级)
- 全表扫描:
type=ALL或TABLE SCAN,且过滤条件列上无可用索引 - 索引失效:列上做了函数运算、隐式类型转换、前导通配符
LIKE '%x'、OR混用不同列 - 回表过多:走了二级索引但返回大量行,需读主表
- 排序开销:
Using filesort且排序字段不在索引中 - 临时表:
Using temporary(常见于GROUP BY+ORDER BY不同列) - 统计信息陈旧:估算行数与实际差一个数量级
第三步:给出建议(必须可执行)
每条建议包含三要素:改什么、为什么、预期效果。
- 索引建议写出完整 DDL,例如
ALTER TABLE orders ADD INDEX idx_user_status_created (user_id, status, created_at); - 索引列顺序按「等值条件 → 范围条件 → 排序」排列,并说明理由
- 改写建议给出改写前后的 SQL 对比
- 不确定收益时给出验证方法,例如对比改写前后的
rows与实际耗时
第四步:输出报告
固定结构,不要省略任何一节:
## 结论
一句话说明瓶颈在哪(不超过 40 字)
## 关键事实
- 访问方式:...
- 扫描行数:...
- 是否回表:...
## 瓶颈分析
逐条说明,每条引用执行计划中的具体字段
## 建议
1. 【索引】DDL + 理由 + 预期
2. 【改写】前后对比 + 理由
## 验证方式
说明怎么验证优化是否生效
## 未确认的信息
列出因材料缺失而无法判断的点,不要编造
硬性约束
- 不编造执行计划:没有
EXPLAIN就明说,不推测type或行数。 - 不承诺具体提速倍数,除非用户提供了实测数据。
- 索引建议必须检查是否已存在相同前缀索引,避免重复建索引。
- 涉及
UPDATE/DELETE时,额外提示锁范围与分批执行。 - 不输出表数据内容、连接串、账号密码等敏感信息。
微信扫一扫