凌晨3点,手机告警震醒。
某支付系统对账接口响应时间飙到8秒,数据库CPU打满。定位到一条看起来人畜无害的SQL:
SELECT t.order_id, t.tx_id, t.amount, t.status, t.created_at,
o.merchant_id, o.user_id,
r.refund_amount, r.refund_reason
FROM transactions t
LEFTJOIN orders o ON t.order_id = o.id
LEFTJOIN refunds r ON t.order_id = r.order_id
WHERE t.status IN ('SUCCESS','FAILED','PROCESSING')
AND t.created_at >= '2026-04-01'
AND t.created_at < '2026-05-01'
ORDERBY t.created_at DESC
LIMIT50;
EXPLAIN一看,倒吸一口气:
transactions 表 1400 万行全表扫描,refunds 表 600 万行也没走索引。
搁以前,翻文档、看索引、改SQL、测试、上线,一套下来至少半天。这次让AI参与进来。
🔍 第一步:把诊断信息喂给AI
EXPLAIN输出和表结构直接丢给GPT,三个问题:
你是一位资深 MySQL DBA。下面是一条慢查询的 EXPLAIN 结果和表结构。
transactions 约1400万行,orders 约50万行,refunds 约600万行。
请分析:
为什么两个表走了全表扫描? 建议创建哪些索引(给出精确 DDL)? SQL 本身是否可以改写?
诊断结果:
transactions 表: 已有 idx_status 和 idx_created_at 两个单列索引,但查询同时用了 status IN(...) 和 created_at 范围条件——优化器只能二选一。选哪个过滤后都剩大量数据,干脆全表扫描。
refunds 表:idx_order_id 存在,但不包含查询需要的 refund_amount 和 refund_reason。回表开销太大,优化器觉得不如直接扫全表。
根因一句话:联合索引缺失。
🔧 第二步:让AI给索引DDL
AI给出的索引:
-- transactions:覆盖索引
ALTERTABLE transactions ADDINDEX idx_status_created
(status, created_at, order_id, tx_id, amount);
-- refunds:覆盖索引
ALTERTABLE refunds ADDINDEX idx_order_id_covering
(order_id, refund_amount, refund_reason);
查询需要的所有列都塞进索引了——覆盖索引,完全避免回表。
⚠️ 但AI不会告诉你:1400万行的表加5列索引,锁多久?占多少磁盘?
自己验证:索引约450MB,可接受。生产环境是 PolarDB,ALGORITHM=INSTANT 秒级完成:
ALTERTABLE transactions
ADDINDEX idx_status_created_cover (status, created_at, order_id, tx_id, amount),
ALGORITHM=INSTANT;
原则:AI出方案,人做安全校验。
✍️ 第三步:SQL改写
索引加完,rows降到28万,还不够。AI提到一个关键点——用延迟关联改写:
-- 子查询只取 transactions 自己的列,利用覆盖索引完成排序和 LIMIT
SELECT t.order_id, t.tx_id, t.amount, t.status, t.created_at,
o.merchant_id, o.user_id,
r.refund_amount, r.refund_reason
FROM (
SELECT order_id, tx_id, amount, status, created_at
FROM transactions
WHEREstatusIN ('SUCCESS','FAILED','PROCESSING')
AND created_at >= '2026-04-01'
AND created_at < '2026-05-01'
ORDERBY created_at DESC
LIMIT50
) t
LEFTJOIN orders o ON t.order_id = o.id
LEFTJOIN refunds r ON t.order_id = r.order_id
ORDERBY t.created_at DESC;
子查询利用覆盖索引直接完成排序+LIMIT,不回表。外层JOIN只关联50行。
新执行计划:
refunds 从全表扫描 600 万行 → ref 只扫 3 行。
📊 验证结果
[原SQL] 返回 50 行,耗时 7.8921 秒
[优化后SQL] 返回 50 行,耗时 0.1187 秒
✅ 结果集一致
加速比: 66.5x
上线后对账接口 P99 从 8 秒降到 150 毫秒以内,数据库 CPU 降了约 15%。
📋 慢查询优化模板
每次遇到慢查询,直接套这个 Prompt:
你是 MySQL 优化专家。以下是慢查询的诊断信息。
请严格按顺序回答:
指出当前执行计划的瓶颈(哪个步骤最耗时、为什么) 给出索引优化建议(精确DDL),说明设计理由 给出SQL改写建议(如有必要),写出优化后SQL 预估优化效果
配合三样东西喂进去:
📄 慢 SQL 原文
📄 EXPLAIN 输出(JSON 格式最好)
📄 表结构(SHOW CREATE TABLE)
⚠️ 三个重要提醒
① 不要把生产数据发给AI。 只发表结构、索引、EXPLAIN。真实数据行不要贴,安全第一。
② AI的输出必须自己验证。 它有时会过度设计——比如建议8列覆盖索引。能加速查询,但严重拖慢写入、吃内存。结合业务读写比例判断,别无脑执行。
③ 让AI校验AI。 SQL改写不放心的话,另开一个对话,把原始SQL和改写后的SQL一起发给AI,让它对比两个SQL是否逻辑等价、指出所有可能的语义差异。交叉验证比单次输出靠谱得多。
这套流程第一次跑通后,后面每次都能复用。不是AI替代DBA,是把人从查文档、猜方案、翻手册的循环里解放出来,把精力花在决策上。
GPT-5.6(ai.onewu.work)完全够用,EXPLAIN输出和建表语句丢进去,按模板走。
有踩过慢查询坑的,进群聊聊 👇

夜雨聆风