AI塞给我两条重复索引|上线前用执行计划拦下

简介: AI 索引建议上生产验证:漏最左前缀、加重复索引。拆这三类错,用 EXPLAIN、key_len、Handler_read 与统计信息逐条验证,讲清写入放大的代价,划清信任边界。

大家好,我是数据库小学妹👋 我踩过的坑,你别再踩。

有段时间我迷上了让 AI 看慢查询、提索引建议。它返回得又快又规整,DDL 写得整整齐齐,我一度觉得这东西又全又对。直到我把一批建议放到生产验证,才发现自己太天真。它漏了最左前缀,还给我加了两条重复索引,等于白花写入代价。

那次之后我改了个习惯。AI 给的每条索引建议,我都不直接上,先拿执行计划过一遍。后来我摸清了它常犯的错,也摸清了它真正能帮上忙的地方。今天把这段历程拆给你。

(后面出现的表名和数字,是我为了讲清楚搭的示意场景,不是真实压测数据。换到你的表,以实测为准。)

它为什么容易被信

AI 提索引建议,逻辑很顺。它看到一条带 WHERE 和 ORDER BY 的 SQL,就照着字段往里塞。语句通顺,DDL 合法,看着没毛病。

问题在于,它看不到三样东西。你表上已经有哪些索引,它不知道。这个查询要扫多少行、哪列的选择性高,它不知道。最关键的,这张表是写入多还是读取多,它更不知道。索引是双刃剑,加错了是要还的。它只看得见你喂给它的那条 SQL,看不见这张表的脾气。

它常犯的三类错

第一类,漏最左前缀。来看一个复现出来的例子。一条查某用户最近订单的语句。

SELECT id, amount, create_time
FROM t_order
WHERE user_id = 88482
ORDER BY create_time DESC
LIMIT 20;

AI 给的是一条以 status 领头的索引。

-- AI 的建议
ALTER TABLE t_order ADD INDEX idx_status_time (status, create_time);

看着合理,其实没用。查询里根本没给 status,索引第一列就落空,user_id 又不在索引里。这条索引对不上这个查询,退化成扫描加排序。它把 ORDER BY 的列记住了,却忽略了领头的等值条件。正确的列序是等值列在前、排序列在后。

-- 正确的列序:等值 user_id 在前,排序列 create_time 在后
ALTER TABLE t_order ADD INDEX idx_user_time (user_id, create_time);

前后差别,用 EXPLAIN 一照就清楚。

方案 key rows Extra
AI 建议(status, create_time) NULL 全表量级 Using where; Using filesort
改为(user_id, create_time) idx_user_time 该用户的订单量级 Using where

再看一眼 key_len。它反映 WHERE 条件实际吃到了联合索引的前几列。AI 那条 key 是 NULL,key_len 也是 NULL,压根没进去。换成 (user_id, create_time),key_len 能对上 user_id 的长度,说明领头列吃上了。排序有没有走索引,key_len 看不出来,得看 Extra 里有没有 Using filesort。可空列和变长列会多算几个字节,对照时按字段定义来,别按裸长度硬套。

还有个细节容易记反。查询里有多个等值条件时,等值列之间谁前谁后都能用上,但都得排在排序列前面。比如 WHERE user_id = ? AND status = ? ORDER BY create_time,(user_id, status, create_time) 和 (status, user_id, create_time) 都能同时吃到过滤和排序。换成 (user_id, create_time, status),排序照样能走索引,但 status 只能在扫描时逐行过滤,范围没被提前收窄。

第二类,重复冗余索引。AI 给一张表提建议时,常常忘了你已经有什么。它可能给你一条 (user_id),可你表上早有 (user_id, create_time)。前者是后者的前缀,白白多占一份写入。也可能一口气提两条,(user_id, status) 和 (user_id),直接冗余。

第三类,对写多的表乱加,制造写放大。每加一条二级索引,INSERT、UPDATE、DELETE 都要多维护一棵树。插入时,索引要先按键值找到插入点。页写满了,还会分裂。更新索引列,等于删一条再插一条。唯一索引还得逐条做唯一性校验。索引一多,buffer pool 被分走,redo 也跟着涨。一张交易流水表,本来就扛着高并发写,AI 为了几条报表查询给你塞四个索引,报表是快了,写入全慢了。高并发下写入延迟开始抖,先数一数索引,别急着怪数据量。这笔账,它从来不替你算。

先量基准,再谈改

我以前犯的错,是拿到建议就想着怎么加。现在我反过来,先把"改之前"的样子量出来。没有基线,你连它有没有用都判断不了。

-- 先清零,后面的计数才算这条查询的
FLUSH STATUS;

-- 8.0.18+:给出真实行数与耗时,不只看估算
EXPLAIN ANALYZE SELECT id, amount, create_time
FROM t_order WHERE user_id = 88482
ORDER BY create_time DESC LIMIT 20;

-- 看这段读写实际碰了多少行
SHOW SESSION STATUS LIKE 'Handler_read%';

EXPLAIN 看的是优化器的估算,EXPLAIN ANALYZE 跑的是真实执行。两个一起看,才知道这条查询现在到底卡在哪。是缺索引,还是索引用错了列序,还是根本该改 SQL。

Handler_read% 别只看总量,得分清楚谁是谁。Handler_read_key 是按索引键定位的次数,说明走了索引。Handler_read_next 是按索引顺序往下读,范围扫描和排序常见。Handler_read_rnd_next 高,基本就是全表扫。三个数摆到一起,是缺索引、列序不对,还是本来就在扫全表,心里就有数了。

逐条验证的四步

验证一条建议,我边走这四步。

先查已有索引,别撞车。

SELECT INDEX_NAME, SEQ_IN_INDEX, COLUMN_NAME, CARDINALITY
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA='app' AND TABLE_NAME='t_order'
ORDER BY INDEX_NAME, SEQ_IN_INDEX;

CARDINALITY 是估算的去重值,不是精确数。拿它估选择率可以,别拿来当判决。大批量导入或删除之后,统计会过期,EXPLAIN 的 rows 也跟着偏。判断前先 ANALYZE TABLE t_order,让优化器拿新统计说话。大表上它会采样索引页,仍有 IO 开销,挑低峰做。

再让 sys 库替你找冗余和没被用过的索引。

SELECT * FROM sys.schema_redundant_indexes WHERE table_schema='app';
SELECT * FROM sys.schema_unused_indexes    WHERE object_schema='app';

第三步,把建议的索引放到 EXPLAIN 里对照,看它到底会不会被选中,key 是不是它,rows 降没降。第四步,评估写入代价,看这张表的读写比,必要的用压测比一下加索引前后的写入吞吐。

-- 8.0:看各索引的读写代价
SELECT * FROM sys.schema_index_statistics WHERE table_schema='app';

一套流程:AI 提,人来判

走到这里,我把用法固定成一条流水线。

AI 提建议,人来判。判断就看三样:已有索引里有没有冗余,这张表的读写比撑不撑得住,查询模式是不是高频。判过之后,再小流量验证,拿真实执行计划确认它真被用上。最后才上线。

一句话,AI 负责"想得到",人负责"该不该"。 它能帮你发现一个你没想到的候选索引,但加不加,是另一回事。

什么场景它能帮上忙

也不是说它一无是处。它的强项在低写入、结构清晰的慢查。

场景 能不能信 为什么
大宽表慢扫描,给过滤列加索引 高 写得少,收益直接
热点写表(交易、流水) 低 写放大它算不到
联合索引的列序设计 低 依赖查询模式与最左前缀,它常排错
覆盖索引、减少回表 中 要看 SELECT 列与真实执行计划
其实该改 SQL,不是加索引 —— 它默认只会"加索引"这一个动作

判断力

AI 能帮你发现可能的索引,但决定加不加,永远要回到两个问题:这张表的读写比是多少,这条查询的真实代价有多高。它给你的是候选,不是结论。把候选当结论,代价会记在你的写入上。

读写比不用拍脑袋。performance_schema 里就有现成的计数,按表拆开看,比凭感觉准得多。

-- 这张表到底是读多还是写多
SELECT OBJECT_NAME, COUNT_READ, COUNT_WRITE
FROM performance_schema.table_io_waits_summary_by_table
WHERE OBJECT_SCHEMA = 'app' AND OBJECT_NAME = 't_order';

读的次数远超写入,加索引这笔账好算。写入比读取还多,就得先答一个问题:这条查询值不值得让每次写入替它买单。AI 答不了这个。它连这张表是流水还是字典都不知道。

真实代价也别只看 EXPLAIN 的估算。去 digest 表里翻这条查询,看它调了多少次、扫了多少行、占总耗时多少。前提是 performance_schema 开着。

SELECT DIGEST_TEXT, COUNT_STAR, SUM_ROWS_EXAMINED,
       ROUND(SUM_TIMER_WAIT/1e9, 0) AS total_ms
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST_TEXT LIKE '%t_order%'
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 5;

一条每天只跑三次的报表查询,扫描行数再大也没必要加索引。为它加,只会拖慢所有写入。反过来,一条每秒几百次、每次扫几万行的查询,收益明摆着。收益是省下的扫描行数乘以调用频次,成本是每次写入多维护一棵树。两边摆到一张纸上,答案不难选。

避坑清单

AI 不知道你的写入压力,索引是双刃剑。写多读少的表,加索引可能赔本,别只看它把查询变快了。每多一条二级索引,插入、更新、删除就多一次维护。这种表加索引,最好压测前后比一比写入吞吐,或者小流量跑几天,盯住写入延迟。加完之后写入变慢,先回头看索引,别急着怪数据库。

重复和冗余的索引会拖慢写入,上线前必查。sys.schema_redundant_indexes 和 schema_unused_indexes 两个视图,能帮你挡掉一大半。但这两个视图只统计 performance_schema 打开之后的访问,新实例别急着拿它当判决书。至少观察一个完整业务周期,比如熬过一次月末报表,再决定删不删。还有个容易漏的细节,(user_id) 被更长的联合索引收着,也算冗余,视图有时未必点全。

最后一条是我自己踩的。我一开始看 AI 生成的 DDL 那么规整,就觉得稳了,差点直接上。被一句话点醒:它没看过你的执行计划,DDL 漂亮不代表索引会被用上。现在每条建议我都先跑 EXPLAIN 对照,再补一次 EXPLAIN ANALYZE 看真实耗时。key 用上了也可能不划算,得看实际扫了多少行、省了多少时间。我给自己定了条规矩:没跑过执行计划的索引建议,不进变更单。

写在最后

AI 提索引建议,最大的坑不是它答错,是我们太信。它看得见语法,看不见你的数据分布、已有索引和写入压力。所以它只能当前排助手,当不了拍板的人。我现在换了用法,先把建表语句、现有索引和这张表的读写情况一起喂给它,再让它提候选。料给足了,它犯的错会少很多,剩下的交给 EXPLAIN 和真实写入数据。加索引是笔权衡的账,AI 擅长把可能性铺开,人得负责把账算平。它写的 DDL 再规整,也只是草稿。

你们会让 AI 帮忙提索引或优化建议吗?提完之后,又是怎么验证的?评论区聊聊。

我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋

相关文章
|
7天前
|
云安全 人工智能 运维
当攻击全面Agent化,你的安全防御能否跟上AI Speed?
多起客户侧AK泄露事件应急的真实观察
1311 6
|
5天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
|
10天前
|
存储 人工智能 安全
千问办公官网入口网页版登录:qwenwork.cn 注册送2000积分、登录送100积分
阿里云千问办公(QwenWork)是AI智能工作平台,支持一句话生成PPT、表格、网页、视频及数据分析。个人免费版送2000积分+每日登录赠100分,含1GB存储、5个发布页;企业版198元/席/月起。阿里千问办公QwenWork官网:https://t.aliyun.com/U/0VCTGt 阿里AI工作平台,一句话完成数据分析、PPT 生成、视频剪辑、网页搭建等复杂任务
|
1月前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
9965 33
|
5天前
|
人工智能 开发者
Qoder CN 大使计划正式开启|无限创造,等你一起
全年免费积分、优先内测、活动支持与更多共创机会,邀请用 Qoder 把想法变成现实的你。
523 6
|
16天前
|
存储 人工智能 并行计算
大模型本地部署终端选型方法论:以 Qwen3.8-27B 为例的四档分层完整流程
本文提出一套大模型本地部署终端选型方法论:定约束、定档位、定框架、定参数四步决策法,配合入门、主力、质量、无损四档分层模型。以 Qwen3.8-27B 实测数据为例,逐环节解读显存、带宽、存储、散热、系统、预算等要素,给出面向不同预算的优选方案、决策自查清单与市场观察框架。文末前瞻 AI 笔记本的 CPU+GPU 与统一内存两条路线,论证四步决策法在新品类上的延续性。
|
7天前
|
Web App开发 人工智能 JavaScript
太猛了,一个月干到15W+,给大家推荐一个最近爆火的开源逆向工具:REA
REA(Reverse Engineer Anything)是近期爆火的开源AI逆向工具,4月发布,1个月内斩获15万+ Star。它让AI Agent无需源码即可分析二进制、APK、JS/Electron、HAR包等17类目标,自动反编译、生成可运行代码,并强制返回带证据与局限的结论。全本地执行,MIT协议,支持Hopper/Ghidra/IDA等引擎,一行命令即可上手。
747 2
太猛了,一个月干到15W+,给大家推荐一个最近爆火的开源逆向工具:REA
|
15天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
1069 1