用 ChatGPT 5.5 辅助排查慢 SQL:从执行耗时到索引优化思路
前言
后端项目做到一定阶段,接口变慢几乎是绕不开的问题。
有时候本地测试很快,到了测试环境或者线上环境就开始变慢;有时候接口本身没有复杂逻辑,但一查日志发现某条 SQL 执行了几百毫秒甚至几秒;还有些情况更麻烦,单次查询不慢,并发一上来整体响应时间就明显抖动。
这类问题如果只靠人工看 SQL、猜索引、翻执行计划,效率并不高。尤其是业务表字段多、关联表多、条件分支多的时候,很容易漏掉关键点。
ChatGPT 5.5 这类大模型在这里比较适合做一件事:辅助整理慢 SQL 排查思路。
它不能替代数据库执行计划,也不能直接告诉你“加这个索引一定好”。但它可以帮你把 SQL、表结构、查询条件、执行计划和现象整理成一条比较清晰的排查路径,减少无效尝试。
本文以一个常见的订单查询接口为例,看看如何用 ChatGPT 5.5 辅助分析慢 SQL 问题。
一、问题场景:订单列表接口变慢
假设有一个订单列表接口:
http
GET /api/order/list
接口用于后台管理系统查询订单,支持以下筛选条件:
- 用户 ID;
- 订单状态;
- 创建时间范围;
- 关键词;
- 分页参数。
最近测试反馈:订单数据量上来之后,这个接口明显变慢。
接口日志中可以看到:
text
2026-01-18 14:21:36.128 INFO [order-service] GET /api/order/list cost=2860ms, pageNo=1, pageSize=20
对应 SQL 大概如下:
sql
SELECT o.id, o.order_no, o.user_id, o.status, o.amount, o.create_time, u.nicknameFROM t_order oLEFT JOIN t_user u ON o.user_id = u.idWHERE 1 = 1 AND o.status = 1 AND o.create_time >= '2026-01-01 00:00:00' AND o.create_time <= '2026-01-18 23:59:59' AND ( o.order_no LIKE '%202601%' OR u.nickname LIKE '%张%' )ORDER BY o.create_time DESCLIMIT 0, 20;
订单表结构简化如下:
sql
CREATE TABLE t_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(64) NOT NULL, user_id BIGINT NOT NULL, status TINYINT NOT NULL, amount DECIMAL(10, 2) NOT NULL, create_time DATETIME NOT NULL, update_time DATETIME NOT NULL);
用户表结构简化如下:
sql
CREATE TABLE t_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, nickname VARCHAR(64) NOT NULL, phone VARCHAR(32), create_time DATETIME NOT NULL);
已有索引:
sql
CREATE INDEX idx_order_user_id ON t_order(user_id);CREATE INDEX idx_order_status ON t_order(status);CREATE INDEX idx_order_create_time ON t_order(create_time);
看起来该有的索引都有,但接口还是慢。
这种情况下,直接问“这条 SQL 怎么优化”往往会得到一些比较泛的建议,比如加索引、减少 LIKE、避免 SELECT *。
更好的方式是让 ChatGPT 5.5 先帮我们整理问题。
二、先让 ChatGPT 5.5 区分事实和猜测
可以这样提问:
text
你是一名 MySQL 慢 SQL 排查助手。下面是一条订单列表查询 SQL、表结构和已有索引。
请帮我完成:1. 只基于已给信息整理已确认事实;2. 分析可能导致慢查询的因素;3. 不要直接给最终结论;4. 按优先级给出后续需要补充的信息;5. 输出适合研发排查记录使用。
【SQL】粘贴 SQL
【表结构】粘贴表结构
【已有索引】粘贴索引
它输出的内容通常会比较接近下面这样:
markdown
## 已确认事实
1. 查询主表为 `t_order`,并通过 `user_id` 左连接 `t_user`。2. 查询条件包含 `status`、`create_time` 和关键词模糊匹配。3. 结果按 `o.create_time DESC` 排序,并使用 `LIMIT 0, 20` 分页。4. `t_order` 上已有单列索引:`user_id`、`status`、`create_time`。5. 关键词查询中存在 `LIKE '%xxx%'` 的写法。6. 查询字段中包含用户昵称,需要关联用户表。
## 可能影响性能的因素
1. `LIKE '%202601%'` 和 `LIKE '%张%'` 前置通配符可能导致索引失效。2. `OR` 条件横跨订单表和用户表,可能增加优化器选择难度。3. `status`、`create_time` 分别有单列索引,但不一定能很好支持组合过滤和排序。4. `ORDER BY create_time DESC LIMIT 20` 如果不能走合适索引,可能产生 filesort。5. 关联用户表后再做昵称模糊匹配,可能扩大扫描范围。6. 如果订单表数据量较大,单列索引选择性不足会导致扫描行数较多。
## 需要补充的信息
1. `EXPLAIN` 执行计划。2. `t_order` 和 `t_user` 的数据量。3. `status = 1` 的数据占比。4. 时间范围内订单数量。5. 关键词条件是否高频使用。6. 是否必须支持订单号和昵称同时模糊搜索。7. 是否有深分页场景。
这个结果的价值在于:它没有一上来就说“加索引”,而是先把可能影响 SQL 的因素拆出来。
慢 SQL 排查时,最忌讳的就是看到慢就盲目加索引。
加错索引不仅没效果,还可能影响写入性能。
三、把 EXPLAIN 结果交给模型分析
接下来我们补充执行计划。
假设执行:
sql
EXPLAINSELECT o.id, o.order_no, o.user_id, o.status, o.amount, o.create_time, u.nicknameFROM t_order oLEFT JOIN t_user u ON o.user_id = u.idWHERE 1 = 1 AND o.status = 1 AND o.create_time >= '2026-01-01 00:00:00' AND o.create_time <= '2026-01-18 23:59:59' AND ( o.order_no LIKE '%202601%' OR u.nickname LIKE '%张%' )ORDER BY o.create_time DESCLIMIT 0, 20;
得到简化后的结果:
text
id: 1select_type: SIMPLEtable: otype: rangepossible_keys: idx_order_status,idx_order_create_timekey: idx_order_create_timerows: 180000Extra: Using index condition; Using where
id: 1select_type: SIMPLEtable: utype: eq_refpossible_keys: PRIMARYkey: PRIMARYrows: 1Extra: Using where
可以继续问 ChatGPT 5.5:
text
下面是这条 SQL 的 EXPLAIN 结果,请帮我分析。
要求:1. 解释每个关键信息代表什么;2. 判断当前执行计划可能的问题;3. 给出下一步验证方向;4. 不要直接假设某个索引一定有效。
比较合理的分析会是:
markdown
## 执行计划解读
1. 主表 `t_order` 使用了 `idx_order_create_time` 索引。2. 访问类型为 `range`,说明根据时间范围做了范围扫描。3. 预计扫描行数为 180000,扫描量较大。4. `Extra` 中出现 `Using where`,说明索引扫描后仍需进一步过滤。5. 用户表 `t_user` 通过主键关联,访问类型为 `eq_ref`,单次关联成本较低。6. 当前主要压力可能集中在订单表扫描和过滤阶段。
## 可能问题
1. 时间范围内订单数量较多,导致 `idx_order_create_time` 扫描行数较大。2. `status = 1` 没有和 `create_time` 形成更有效的组合过滤。3. `LIKE '%xxx%'` 条件无法有效利用普通 BTree 索引。4. `OR` 条件涉及两张表,可能导致过滤效率下降。5. 如果排序无法完全利用索引,可能存在额外排序成本。
## 下一步验证
1. 查看 `status = 1` 的数据占比。2. 分别去掉关键词条件、去掉用户昵称条件测试耗时。3. 测试组合索引 `(status, create_time)` 的效果。4. 查看是否存在 `Using filesort`。5. 使用 `EXPLAIN ANALYZE` 查看真实耗时和真实扫描行数。
这里模型给出的不是最终答案,而是帮助我们把执行计划翻译成更容易理解的排查步骤。
四、常见问题一:单列索引不等于查询就快
当前订单表已有三个索引:
sql
CREATE INDEX idx_order_user_id ON t_order(user_id);CREATE INDEX idx_order_status ON t_order(status);CREATE INDEX idx_order_create_time ON t_order(create_time);
很多人看到这里会觉得:状态有索引,时间有索引,用户 ID 也有索引,应该够用了。
但这条 SQL 的核心条件是:
sql
WHERE o.status = 1 AND o.create_time >= ... AND o.create_time <= ...ORDER BY o.create_time DESCLIMIT 0, 20
这种查询往往更适合考虑组合索引,例如:
sql
CREATE INDEX idx_order_status_create_timeON t_order(status, create_time);
可以让 ChatGPT 5.5 帮你分析为什么这个组合索引可能有用:
text
对于下面这个查询条件:status = 1create_time between ...order by create_time desclimit 20
请解释为什么组合索引 (status, create_time) 可能比单列索引更适合。
输出可以整理为:
markdown
组合索引 `(status, create_time)` 可能更适合的原因:
1. `status` 是等值查询,可以作为组合索引第一列。2. `create_time` 是范围查询,可以在同一个索引中继续缩小扫描范围。3. 查询需要按照 `create_time` 排序,如果索引顺序匹配,可能减少额外排序成本。4. 相比只使用 `idx_order_create_time`,组合索引可以先过滤状态,再扫描时间范围。5. 如果 `status = 1` 的数据占比不是特别高,组合索引可以明显减少扫描行数。
不过需要注意,这里用了“可能”。
因为索引是否有效,还取决于数据分布。
如果 status = 1 占全表 95%,那么这个字段的过滤效果就很弱。
这时候组合索引仍可能有帮助,但效果未必明显。
五、常见问题二:LIKE '%关键词%' 很难走普通索引
SQL 中有两个模糊查询:
sql
o.order_no LIKE '%202601%'OR u.nickname LIKE '%张%'
这种前后都有 % 的写法,对普通 BTree 索引非常不友好。
如果业务允许,可以把订单号查询改成前缀匹配:
sql
o.order_no LIKE '202601%'
这样才有机会利用订单号索引:
sql
CREATE INDEX idx_order_no ON t_order(order_no);
但如果必须支持任意位置模糊匹配,比如:
sql
LIKE '%202601%'
那普通索引基本帮不上太多。
可以让 ChatGPT 5.5 继续帮我们拆方案:
text
订单号和用户昵称都需要支持关键词搜索,现在使用 LIKE '%keyword%'。请给出几种优化思路,并说明适用条件和缺点。
可能得到这样的结果:
markdown
## 方案一:改为前缀匹配
示例:
```sqlo.order_no LIKE '202601%'
适用条件:
- 订单号本身有明确前缀规则;
- 用户搜索习惯可以接受从开头匹配。
优点:
- 可以利用普通 BTree 索引;
- 改造成本低。
缺点:
- 不支持任意位置匹配。
方案二:拆分搜索逻辑
订单号搜索和昵称搜索分开处理:
- 如果关键词像订单号,只查订单表;
- 如果关键词像昵称,再关联用户表;
- 避免每次都同时 OR 两个字段。
优点:
- 减少无效关联和扫描;
- 查询路径更清晰。
缺点:
- 需要业务规则判断关键词类型。
方案三:引入搜索引擎
如 Elasticsearch、OpenSearch 等。
适用条件:
- 搜索需求复杂;
- 数据量较大;
- 需要分词、模糊搜索、排序等能力。
优点:
- 搜索能力强;
- 更适合复杂关键词查询。
缺点:
- 引入额外组件;
- 存在数据同步和一致性问题。
方案四:建立冗余搜索字段
在订单表中冗余用户昵称或搜索关键字段,减少 join 查询。
优点:
- 查询链路简单;
- 对后台列表查询比较友好。
缺点:
- 数据更新时需要同步;
- 存在冗余字段一致性问题。
这个输出就比较适合作为方案讨论的基础。
---
## 六、常见问题三:OR 条件可能让优化变复杂
原 SQL 中的关键词条件是:
```sqlAND ( o.order_no LIKE '%202601%' OR u.nickname LIKE '%张%')
这里有两个特点:
OR连接了两个条件;- 两个条件还分别位于不同表。
这种写法对优化器并不友好。
如果数据量不大问题不明显,但数据量上来后,很容易变慢。
一种常见改法是根据关键词类型拆 SQL。
例如订单号有固定格式:
text
202601180001
那么当关键词符合订单号格式时,只查订单号:
sql
SELECT o.id, o.order_no, o.user_id, o.status, o.amount, o.create_time, u.nicknameFROM t_order oLEFT JOIN t_user u ON o.user_id = u.idWHERE o.status = 1 AND o.create_time >= '2026-01-01 00:00:00' AND o.create_time <= '2026-01-18 23:59:59' AND o.order_no LIKE '202601%'ORDER BY o.create_time DESCLIMIT 0, 20;
如果关键词明显是昵称,再走用户昵称查询路径。
也可以先查用户 ID:
sql
SELECT idFROM t_userWHERE nickname LIKE '%张%';
再查订单:
sql
SELECT o.id, o.order_no, o.user_id, o.status, o.amount, o.create_timeFROM t_order oWHERE o.user_id IN (...) AND o.status = 1 AND o.create_time >= '2026-01-01 00:00:00' AND o.create_time <= '2026-01-18 23:59:59'ORDER BY o.create_time DESCLIMIT 0, 20;
当然,这种方式也不是一定更快。
如果昵称匹配出来的用户很多,IN 列表也可能变大。最终还是要靠执行计划和真实压测验证。
七、让 ChatGPT 5.5 生成验证清单
慢 SQL 优化最重要的是验证,而不是凭感觉改。
可以继续这样问:
text
针对这条订单列表慢 SQL,请帮我生成一个优化验证清单。
要求:1. 每一项都能实际执行;2. 包含执行计划、耗时、扫描行数、索引效果;3. 区分必须验证和可选验证;4. 输出表格。
可以得到类似表格:
| 验证项 | 类型 | 观察指标 | 目的 |
|---|---|---|---|
| 查看原 SQL 的 EXPLAIN | 必须 | key、rows、Extra | 确认当前执行计划 |
| 使用 EXPLAIN ANALYZE | 必须 | 实际耗时、实际扫描行数 | 对比估算和真实执行情况 |
| 去掉关键词条件测试 | 必须 | 查询耗时是否明显下降 | 判断 LIKE/OR 是否为主要瓶颈 |
| 去掉用户昵称搜索测试 | 必须 | join 后过滤成本 | 判断跨表模糊匹配影响 |
增加 (status, create_time) 索引后测试 |
必须 | rows、是否 filesort、耗时 | 验证组合索引效果 |
| 改订单号为前缀匹配测试 | 可选 | 是否使用订单号索引 | 验证订单号搜索优化空间 |
| 拆分订单号和昵称搜索 SQL | 可选 | 不同路径的耗时 | 验证拆查询是否更稳定 |
| 检查慢查询日志 | 必须 | 执行频率、平均耗时 | 判断是否为高频慢 SQL |
| 检查分页页码 | 可选 | 深分页耗时 | 判断是否存在 LIMIT offset 问题 |
这种清单很适合放到 issue 或技术方案里。
团队沟通时,也比一句“这个 SQL 要优化”清楚得多。
八、一个可能的优化方向
在当前信息下,可以先尝试一个相对基础的优化方向。
1. 增加组合索引
sql
CREATE INDEX idx_order_status_create_timeON t_order(status, create_time DESC);
如果 MySQL 版本对降序索引支持有限,也可以使用:
sql
CREATE INDEX idx_order_status_create_timeON t_order(status, create_time);
然后重新执行:
sql
EXPLAIN SELECT ...
重点观察:
key是否使用了新索引;rows是否明显下降;Extra中是否还有Using filesort;- 实际查询耗时是否下降。
2. 拆分关键词搜索
原始写法:
sql
AND ( o.order_no LIKE '%202601%' OR u.nickname LIKE '%张%')
可以根据业务规则拆开。
如果关键词像订单号:
sql
AND o.order_no LIKE '202601%'
如果关键词像昵称:
sql
AND u.nickname LIKE '%张%'
甚至在昵称查询场景下先定位用户,再查订单。
3. 限制后台查询时间范围
后台列表查询如果默认查全量,非常容易慢。
可以在产品层面限制默认时间范围,例如:
- 默认查最近 7 天;
- 最多查询 90 天;
- 超过范围走导出任务。
这类优化不只是技术问题,也和产品交互有关。
4. 避免深分页
如果后台存在这种查询:
sql
LIMIT 100000, 20
性能会很差。
可以考虑改成基于游标的翻页:
sql
WHERE create_time < 上一页最后一条记录的create_timeORDER BY create_time DESCLIMIT 20;
或者结合 id 做稳定排序:
sql
WHERE (create_time, id) < (?, ?)ORDER BY create_time DESC, id DESCLIMIT 20;
九、让 ChatGPT 5.5 辅助写复盘文档
SQL 优化完成后,最好不要只在群里说一句“已优化”。
可以让 ChatGPT 5.5 帮忙整理成复盘文档。
Prompt 示例:
text
请根据下面的慢 SQL 排查过程,整理一份技术复盘。
要求:1. 包含问题背景、影响范围、排查过程、根因分析、优化方案、验证结果、后续建议;2. 不要编造没有提供的数据;3. 对不确定内容标记为待确认;4. 语言适合 CSDN 技术文章或团队内部文档。
复盘结构可以是:
markdown
## 1. 问题背景
订单列表接口在数据量增加后响应变慢,接口平均耗时升高。
## 2. 影响范围
- 后台订单列表查询;- 高峰期查询响应变慢;- 暂未影响订单创建主流程。
## 3. 排查过程
1. 查看接口日志,确认耗时集中在订单查询。2. 获取原 SQL 和执行计划。3. 发现订单表扫描行数较多。4. 分别测试去掉关键词条件、去掉昵称条件后的耗时。5. 验证组合索引效果。6. 对关键词查询进行拆分。
## 4. 优化方案
1. 增加组合索引 `(status, create_time)`。2. 根据关键词类型拆分查询路径。3. 限制默认查询时间范围。4. 后续评估是否引入搜索引擎。
## 5. 验证结果
待补充真实压测数据。
## 6. 后续建议
1. 对高频后台查询建立慢 SQL 监控。2. 新增复杂查询前先评估索引。3. 对关键词搜索类需求单独设计查询方案。
这种复盘文档对团队很有价值。
因为 SQL 优化不是一次性工作,后面类似问题还会出现。把排查过程沉淀下来,下次会快很多。
十、使用 ChatGPT 5.5 分析慢 SQL 时的注意点
虽然 ChatGPT 5.5 可以辅助分析 SQL,但有几个点一定要注意。
1. 不要让模型凭空猜数据分布
SQL 优化高度依赖数据分布。
同一条 SQL,在 10 万数据和 1 亿数据下,优化策略可能完全不同。
最好提供:
- 表数据量;
- 字段基数;
- 条件命中比例;
- 执行计划;
- 慢查询日志;
- 实际耗时。
2. 不要盲目照抄索引建议
模型可能会建议很多索引,但索引不是越多越好。
索引会带来:
- 写入变慢;
- 占用磁盘;
- 增加维护成本;
- 可能让优化器选择变复杂。
上线前一定要在测试环境验证。
3. 不要只看 EXPLAIN
EXPLAIN 是估算,不能完全代表真实执行情况。
如果 MySQL 版本支持,建议配合:
sql
EXPLAIN ANALYZE
看真实执行时间和真实扫描行数。
4. 不要忽略业务改造
有些慢查询不是单纯靠索引能解决的。
比如任意关键词搜索、深分页、大范围导出,这些更适合从业务设计上调整。
5. 不要把模型输出当最终结论
模型输出应该作为排查参考,而不是上线依据。
最终是否有效,要靠执行计划、压测数据和线上监控确认。
总结
ChatGPT 5.5 用在慢 SQL 排查中,比较合适的位置不是“直接给答案”,而是帮助开发者把信息整理清楚:
- SQL 当前做了什么;
- 哪些条件可能影响索引;
- 执行计划暴露了哪些问题;
- 下一步该验证什么;
- 优化方案有哪些取舍;
- 最终如何形成复盘文档。
对于订单列表、后台查询、关键词搜索、分页接口这类常见慢 SQL 场景,它能明显提高排查效率。
但数据库优化最终还是要回到真实数据上。
执行计划、扫描行数、字段选择性、查询频率、并发压力,这些才是决定优化方案是否有效的关键。
简单说:ChatGPT 5.5 可以帮你少走弯路,但不能替你完成验证。真正可靠的优化,一定是模型辅助分析加上实际数据验证。
更多推荐


所有评论(0)