
1. 从 SQL_ID 到真实执行计划ORACLE 执行计划查询到底在查什么ORACLE 执行计划查询说白了就是让数据库把它“准备怎么跑这条 SQL”的路线图交出来。你手里只有一条慢 SQL 或者一个 SQL_ID想知道它到底走了索引还是全表扫、哪一步最耗时、预估行数和真实行数差了多少靠的就是执行计划。它适合每天跟慢查询打交道的 DBA、后端开发也适合刚接手一套老系统、被一条跑 20 多秒的报表 SQL 卡住的同学。很多人第一次查执行计划会直接用EXPLAIN PLAN FOR然后DBMS_XPLAN.DISPLAY。这个方式能看但有个坑它给的是预估计划不是真实跑出来的计划。预估计划里的 E-Rows 是优化器猜的A-Time、A-Rows 这些真实数据根本没有。你排查慢 SQL 时最需要的恰恰是真实行数和真实耗时所以更推荐用DBMS_XPLAN.DISPLAY_CURSOR配合gather_plan_statistics来拿实际执行计划。日常排障的链路其实很固定先定位 SQL_ID再决定用哪种方式采集运行时统计最后把DISPLAY_CURSOR的输出读明白。问题在于这条链路里经常要查文档、对参数、翻报错如果每个工具都单独配一套 Key 和地址切换成本很高。我现在的做法是把模型调用统一走 TaoToken 的 Key 和 API 通道查语法、解释报错、生成排查脚本都在一个入口里完成省掉来回找配置的麻烦。下面按“定位 SQL_ID → 采集统计 → 输出计划 → 解读 → 排错”的顺序把可复制的脚本和配置都给你。先明确一个判断标准A-Rows 和 A-Time 才是真实值。E-Rows 是优化器估算A-Rows 是实际返回行数。两者差距大往往意味着统计信息过期或者谓词估算失真这是后面解读计划时最该盯的地方。2. TaoToken 统一 Key 前置把诊断脚本和模型通道一次配好在写查询脚本之前先把 TaoToken 的通道配好。原因很实际ORACLE 执行计划查询涉及大量参数记忆比如display_cursor的 format 取值、allstats last和allstats peeked_binds的区别、v$sql里哪些字段能过滤出目标 SQL。这些细节我基本靠模型对话来确认而不是每次翻文档。统一 Key 之后模型对话、接入文档、API Keys 管理都在同一套体系里不用为每个工具单独维护凭证。TaoToken 官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置 Base URL 时用这个干净的地址。你需要准备三件套Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiAPI Key 在控制台的 API Keys 页面生成Model ID 按你实际要用的模型填。如果你用的是 Claude Code 这类编码工具配置方式是在 settings 里指定 Base URL 和 Key如果用的是 Cline 这类带 MCP 的插件同样在模型提供方里选自定义 OpenAI 兼容接口把 Base URL 指向 TaoToken。Codex 的话认证信息写在auth.json里Base URL 和 Key 对应填好即可。这三件套缺一不可尤其是 Model ID填错会直接报模型不存在。配好之后你可以先在模型对话里验证一下通道是否通问一句“ORACLE display_cursor 的 format 参数 allstats last 是什么意思”能正常返回就说明 Key 和地址没问题。这一步别跳过因为后面排查 SQL 时如果模型通道不通你会误以为是数据库的问题实际是配置问题。需要提醒的是TaoToken 在这里的角色是统一的模型调用通道不是数据库代理也不碰你的生产库。你的 SQL 还是在本地客户端或堡垒机上执行模型只负责帮你解释语法、生成脚本、分析报错。这个边界要清楚避免把两件事混在一起。3. 可复制配置SQL_ID 定位与 DBMS_XPLAN 采集脚本这一节给的是能直接粘贴执行的脚本。先看怎么定位 SQL_ID。最常用的是查v$sql按最近活跃时间倒序过滤掉系统自身的查询select SQL_ID, v.LAST_ACTIVE_TIME, v.SQL_FULLTEXT from v$sql v where v.LAST_ACTIVE_TIME to_date(2024/01/10 17:00:00, yyyy/mm/dd hh24:mi:ss) and v.SQL_FULLTEXT not like %SQL_ID% and v.SQL_FULLTEXT like %select % order by v.LAST_ACTIVE_TIME desc;拿到 SQL_ID 后采集真实执行计划有两种方式。第一种是会话级打开统计采集alter session set statistics_level all;这个设置对当前会话窗口有效执行完目标 SQL 后再查计划就能看到 A-Rows、A-Time、Buffers 这些真实数据。缺点是每条要诊断的 SQL 都得先开这个开关会话一关就失效。第二种是不改会话直接在 SQL 里加 hintselect /* gather_plan_statistics */ count(*) from pa_charges_details;这种方式每条语句都要加比较麻烦不推荐大批量排查时用。我一般用第一种会话级打开一次诊断多条。采集到统计后用DBMS_XPLAN.DISPLAY_CURSOR输出计划select * from table(dbms_xplan.display_cursor(79qcx7ttjnqrv, null, allstats last));第一个参数是 SQL_ID第二个参数null表示取该 SQL 的所有子游标第三个参数allstats last表示显示最近一次执行的运行时统计。如果你要看绑定变量可以换成allstats peeked_binds。如果你用 TaoToken 的模型通道来生成或校验这些脚本可以在对话里直接贴表结构让它帮你补全过滤条件。配置片段方面以 OpenAI 兼容的 settings 为例Base URL 和 Key 这样填{ base_url: https://taotoken.net/api, api_key: 你的_API_KEY, model: 你的_MODEL_ID }Cline MCP 的配置类似在 provider 里选 OpenAI CompatibleBase URL 填https://taotoken.net/apiKey 填控制台生成的Model ID 按实际填。Codex 的auth.json里对应字段是base_url和api_key同样三件套齐全。这三处配置的核心都是 Base URL Key Model ID缺一个都会失败。4. 验证请求与成功结果读懂 A-Rows 和 A-Time脚本跑通后你会看到类似这样的输出| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | | 0 | SELECT STATEMENT | | 1 | | 50 | 00:00:24.93 | 163K | 25395 | |* 1 | HASH JOIN | | 1 | 1 | 50 | 00:00:24.93 | 163K | 25395 | |* 2 | HASH JOIN | | 1 | 1 | 1140K | 00:00:14.61 | 163K | 12915 | |* 3 | HASH JOIN | | 1 | 1 | 1140K | 00:00:04.51 | 163K | 0 | |* 4 | INDEX RANGE SCAN | PA_CHARGES_DETAILS_..._INDEX2 | 1 | 1 | 1208K | 00:00:01.66 | 103K | 0 | |* 5 | INDEX FAST FULL SCAN | PA_CHARGE_POINT_INDEX2 | 1 | 1 | 1451K | 00:00:01.09 | 59607 | 0 | | 6 | TABLE ACCESS FULL | BD_WA_SALARY_PERFORMANCEUNIT | 1 | 1 | 277 | 00:00:00.01 | 37 | 0 |怎么读先看 Id 0 的 A-Time这里是 24.93 秒说明整条 SQL 跑了将近 25 秒。然后往下找耗时占比大的步骤。Id 2 的 A-Time 是 14.61 秒Id 3 是 4.51 秒这两个 HASH JOIN 是主要耗时点。再看 A-RowsId 2 和 Id 3 都返回了 1140K 行说明中间结果集很大哈希连接在大量数据上做匹配慢是必然的。重点对比 E-Rows 和 A-Rows。Id 4 的 E-Rows 是 1A-Rows 是 1208K差了六个数量级。这说明优化器严重低估了这张索引扫描的返回行数很可能统计信息过期导致它选了一个不适合的执行路径。这种偏差就是你要动手优化的信号先收集统计信息再看计划是否变化。验证请求是否成功可以看两个点一是DISPLAY_CURSOR有没有返回行返回空通常意味着 SQL_ID 不对或者游标已经被刷出共享池二是 A-Time 列有没有值如果全是空说明统计采集没生效回去检查statistics_level是否设为 all或者 hint 有没有加对。如果你想用模型通道辅助解读可以把这段计划贴进模型对话让它帮你标出耗时最大的步骤和行数偏差最大的节点。TaoToken 的模型对话入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 接入文档在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 对应的文档页。这样你既拿到了真实计划又能快速得到解读建议。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth排查执行计划时报错往往不在 SQL 本身而在通道配置。下面几个是我实际遇到过的。401 Unauthorized模型通道返回 401基本是 API Key 填错或过期。检查api_key字段有没有多余空格Key 是否在控制台被删除。注意 Base URL 要用https://taotoken.net/api不要带 UTM 参数带参数的地址可能导致鉴权失败。local proxy failed这个报错通常出现在本地代理配置上。如果你在 settings 里配了本地代理地址但代理没启动或者端口不对就会报这个。解决方式是确认代理进程在跑或者直接去掉代理配置让请求走直连。注意这里说的是本地开发环境的网络配置不是让你去搞什么特殊网络手段纯粹是本地端口和进程的问题。reading choices 相关报错这类错误一般是模型返回格式不符合预期比如你用的 Model ID 不支持当前接口的返回结构。检查 Model ID 是否填对是否和 Base URL 对应的服务匹配。三件套里 Model ID 最容易填错建议从控制台复制。OAuth 报错如果你用的是 Claude Code 这类带 OAuth 流程的工具报 OAuth 失败通常是认证信息没写进auth.json或者 Base URL 和 Key 不匹配。Codex 的auth.json里要同时有base_url和api_key缺一个都会走到 OAuth 分支然后失败。把三件套补齐重启工具再试。数据库侧的常见错也要提一句DISPLAY_CURSOR返回空先确认 SQL_ID 是否还在v$sql里共享池被刷出后就查不到了statistics_level没开的话A-Rows 和 A-Time 会是空值不是报错但结果没意义。这两点排查顺序是先确认通道通再确认统计采集开最后看计划输出。6. 把诊断链路固定下来统一 Key 之后的日常用法配好 TaoToken 统一 Key 之后我的日常流程是这样的遇到慢 SQL先在客户端执行alter session set statistics_level all跑一遍目标语句查v$sql拿 SQL_ID再用DISPLAY_CURSOR输出计划。计划里重点看 A-Time 最大的节点和 E-Rows 与 A-Rows 偏差最大的节点。如果对某个 format 参数不确定直接在模型对话里问不用切工具。长期做 SQL 诊断和 Agent 类编码任务的话可以考虑 Coding Plan入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。API Keys 管理在 https://taotoken.net/api 对应的控制台页面。需要生成新 Key 或者查看用量都在那里操作。最后给一个实用技巧把常用的DISPLAY_CURSOR查询存成脚本片段SQL_ID 作为参数传入这样每次排查不用重新敲。模型通道那边也可以把常见的 format 取值整理成提示词模板问一次存一次下次直接复用。执行计划查询这件事脚本固定下来之后剩下的就是读计划的经验而经验靠一次次对比 A-Rows 和 E-Rows 积累。