关于 pythia-tune
pythia-tune 是用于诊断和调优 SQL 或 PL/SQL 性能的技能,面向维护数据库应用的开发者。它要求先用执行计划和统计信息定位原因,再提出单项改动,并以相同方式复测。
主要功能
- 01获取应用实际执行的 SQL
- 02检查执行计划与表统计信息
- 03按清单诊断性能原因
- 04每次提出一项调整并说明代价
- 05改动前后使用相同方法测量
适用场景
- 01调查大型表的全表扫描
- 02诊断估算行数或连接异常
- 03评估索引或 SQL 改写效果
- 04复测改动并决定是否回退
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ thaildhe172591/ pythia --skill pythia-tune安装后在 Claude Code 中输入/pythia-tune确认已加载。
附带文件reference/tuning-checklist.md
详细介绍
调优查询或单元
开始时宣告:“正在使用 pythia-tune —— 先测量,再改动。”
**阶段:**了解 → 询问 → 执行——先制定计划并查看统计数据,只提出一项改动,然后用相同的测量方法复测
性能方面的经验之谈,往往是最自信的错误说法。“加个索引”“用个提示”“改写成连接”——有些执行计划适用,有些则有害,只有执行计划能说明哪种情况适用。没有前后对比就调优,无异于多绕几步来猜测。
铁律
NO TUNING CHANGE WITHOUT A MEASUREMENT BEFORE AND THE SAME ONE AFTER
工作流程
- 获取实际语句。 获取应用实际运行的准确 SQL——通过
pythia src/pythia grep获取,并将绑定变量保留为绑定变量(:id), 不要粘贴字面值:字面值可能产生与绑定变量不同的执行计划。 - 测量。
pythia explain "<the select>"——优化器的执行计划;查看行数 (基数)、成本、每张表的访问路径,以及 pythia 添加的-- note:行(全表扫描、笛卡尔连接、隐式类型转换、动态采样)。- 对执行计划中的每张表运行
pythia stats <TABLE>——查看行数、 统计信息的收集时间、STALE、索引及其列,以及未建索引的外键。 - 对于 DML,解释用于查找其操作行的
SELECT。
- 按顺序使用清单进行诊断(
reference/tuning-checklist.md)—— 优先排查成本最低且最常见的原因:统计信息、无法使用索引的谓词、 错误或缺失的索引、连接形态,然后是逐行处理 PL/SQL。用一句话指出原因, 并引用能证明这一点的执行计划行。 - 只提出一项改动,说明它对执行计划的预期影响及其成本:在该表上加索引
会拖慢每次写入,而且属于
structural改动(使用pythia-table进行设计);改写会改变代码(使用pythia-write,先说明影响)。 在共享架构上收集统计信息应由 DBA 或所有者决定——明确说明这一点, 不要自行执行。 - 通过常规流程应用改动——使用
pythia apply/pythia deploy, 绝不使用提示,也不要手动创建索引。 - 使用第 2 步中的相同命令重新测量,并报告前后对比:执行计划形态、 成本、基数。如果没有改善,就如实说明并回滚——没有帮助的改动仍然有成本。
此工具包可以和不可以测量的内容
explain使用 EXPLAIN PLAN +DBMS_XPLAN.DISPLAY:它提供估算的 执行计划,且不受许可证限制。运行时实际使用的执行计划可能不同 (绑定变量窥探、自适应计划)——DBMS_XPLAN.DISPLAY_CURSOR需要V$访问权限,而 AWR、ASH 和 SQL Tuning Advisor 需要 Diagnostics/Tuning Pack 许可证。未获开发者确认许可证前,绝不要使用或推荐它们。- 实际耗时:
pythia sql "<select>"会运行查询;在开发架构上用 shell 的time包裹它,获取粗略耗时,并说明这是粗略估算。
常见原因,按发生频率排列
| 执行计划中的症状 | 常见原因 | 常见修复方法 |
|---|---|---|
| 行数估算与实际相差很大,出现“dynamic statistics used” | 统计信息缺失或过期 | 请所有者收集统计信息(DBMS_STATS) |
大表上出现 TABLE ACCESS FULL,且谓词具有选择性 | 索引列上使用了函数或隐式类型转换、LIKE 中以 % 开头、没有索引 | 将谓词改写为可使用索引的形式;然后再考虑加索引 |
谓词中出现 INTERNAL_FUNCTION、TO_NUMBER("COL") | 将 VARCHAR2 列与数字比较,或将 DATE 与字符串比较 | 比较相同类型;在字面值一侧使用带格式的 TO_DATE |
MERGE JOIN CARTESIAN | 缺少连接谓词 | 添加连接谓词 |
FILTER 中使用了 NOT IN | NOT IN 中的列允许 NULL | 使用 NOT EXISTS |
| 一个快速查询被调用了数千次 | PL/SQL 逐行处理、SQL 中每行调用一个函数 | 使用一个基于集合的语句;使用 BULK COLLECT LIMIT + FORALL;标量子查询缓存;对稳定的查找使用 RESULT_CACHE |
| 子游标很多,解析时间很长 | 动态 SQL 中使用字面值而非绑定变量 | 使用绑定变量(USING) |
危险信号 — 一旦发现自己有以下想法,请立即停止
| 想法 | 实际情况 |
|---|---|
| “加个提示就行” | 提示会让今天的计划无法适应明天的数据。解决根因;提示是最后手段,且须经开发者批准。 |
| “建个索引就能解决” | 只有谓词能使用该索引时才行,而且每次写入都会因此付出代价。用执行计划验证。 |
| “它很慢,所以是数据库的问题” | 执行计划会说明问题出在 SQL、数据,还是周围的 10,000 次调用。 |
| “我自己收集统计信息” | 在共享架构中,这会改变所有人的执行计划。由所有者决定。 |
| “感觉快了” | 必须用相同的方法测量前后结果,否则就没有发生。 |
| “我来检查一下 AWR” | 需要许可证。先询问。 |
何时不应使用此技能
- 代码有误,而不是运行缓慢 →
pythia-review。 - 设计诊断要求的索引 →
pythia-table。 - 编写改写后的 PL/SQL →
pythia-write(在使用pythia-impact之后)。
评论
支持 Markdown