SuperAPI AI 工具集

pythia-tune

数据与分析

查看项目

更新于 10-16 05:24

技能介绍

调优一个查询或一个单元

开始时声明:"Using pythia-tune — measuring before changing anything."

阶段:Learn → Ask → Do——先看计划和统计信息,只提出一处改动,之后用同样的方式测量。

性能流言是最自信的一种错误。"加个索引""用个 hint""改写成 join"——每一条对某些计划是对的,对另一些则有害,只有执行计划能说明是哪一种。没有前后对照的调优,只是多走了几步的猜测。

铁律

没有改动前的测量和改动后相同的测量,就不做任何调优改动。

工作流程

获取真实语句。应用实际运行的精确 SQL——通过 pythia src / pythia grep 获取,带绑定变量(以 :id 形式),而不是粘贴字面量:字面量可能与绑定变量得到不同的计划。

测量。

pythia explain "<the select>"——优化器的计划;阅读 rows(基数)、cost、每张表的访问路径,以及 pythia 添加的 -- note: 行(全表扫描、笛卡尔连接、隐式转换、动态采样)。

对计划中的每张表运行 pythia stats <TABLE>——行数、统计信息的收集时间、STALE 状态、索引及其列、未加索引的外键。

对于 DML,explain 定位其行的那条 SELECT。

按清单诊断(reference/tuning-checklist.md),按顺序——先查最便宜且最常见的原因:统计信息、无法使用索引的谓词、错误或缺失的索引、连接形态,然后是 PL/SQL 逐行工作。用一句话说出原因,并给出证明它的计划行。

提出一处改动,说明它对计划的预期影响及其代价:索引会拖慢该表的每次写入,且属于结构性变动(用 pythia-table 设计);重写会改动代码(pythia-write,先做影响评估)。在共享 schema 上收集统计信息是 DBA 或属主的事——要说明,不要擅自运行。

通过正常入口应用——pythia apply / pythia deploy——绝不手工创建 hint 或索引。

用第 2 步完全相同的命令再次测量,并报告前后对比:计划形态、cost、基数。若没有改善,就说明并回滚——没有帮助的改动仍然有代价。

本工具包能测量与不能测量的内容

explain 是 EXPLAIN PLAN + DBMS_XPLAN.DISPLAY:估算计划,license 安全。实际运行时使用的计划可能不同(绑定变量窥探、自适应计划)——DBMS_XPLAN.DISPLAY_CURSOR 需要 V$ 访问权限,AWR、ASH 和 SQL Tuning Advisor 需要 Diagnostics/Tuning Pack 许可。未经开发者确认许可,绝不使用或推荐它们。

真实计时:pythia sql "<select>" 运行一条查询;在开发 schema 上用 shell 的 time 包一下可得到粗略数字,并说明它是粗略的。

常见原因(按频率)

计划中的症状 | 常见原因 | 常见修复

行估算与实际情况相差甚远、"dynamic statistics used" | 统计信息缺失或过期 | 请属主收集统计信息(DBMS_STATS)

大表上带选择性谓词的 TABLE ACCESS FULL | 索引列上有函数或隐式转换、LIKE 以 % 开头、没有索引 | 重写谓词使其可被索引使用;然后考虑加索引

谓词中出现 INTERNAL_FUNCTION、TO_NUMBER("COL") | 将 VARCHAR2 列与数字比较、DATE 与字符串比较 | 比较相同类型;在字面量侧用带格式的 TO_DATE

MERGE JOIN CARTESIAN | 缺少连接谓词 | 补上

带 NOT IN 的 FILTER | NOT IN 下的可空列 | 改用 NOT EXISTS

一个快速查询被调用数千次 | 逐行 PL/SQL、SQL 中每行调用一个函数 | 一条基于集合的语句;BULK COLLECT LIMIT + FORALL;标量子查询缓存;对稳定查找使用 RESULT_CACHE

子游标众多、解析时间高 | 动态 SQL 中用字面量而非绑定变量 | 使用绑定变量(USING)

红旗——如果你发现自己这样想,就停下

想法 | 现实

"直接加个 hint" | hint 会把今天的计划冻结在明天的数据上。修复根因;hint 是需开发者批准的最后手段。

"加索引就能解决" | 只有当谓词能用它时才行——而且它拖累每次写入。用计划来证明。

"它慢,所以是数据库的错" | 计划会说明是 SQL、数据,还是围绕它的上万次调用。

"我自己收统计信息" | 在共享 schema 上会改变所有人的每个计划。这是属主的决定。

"感觉变快了" | 同样的测量,前后对照,否则就等于没发生。

"让我看看 AWR" | 需要许可。先问。

何时不使用此技能

代码本身是错的而非慢的 → 用 pythia-review。

要设计诊断所要求的索引 → 用 pythia-table。

要编写重写后的 PL/SQL → 用 pythia-write(在 pythia-impact 之后)。