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 を使用します。変更を加える前に測定します。」
フェーズ: Learn → Ask → Do — まず計画と統計情報を確認し、変更案を1つ提示してから、同じ方法で再測定します
パフォーマンスに関する俗説は、最も自信満々に間違っているものです。「インデックスを追加する」「ヒントを使う」「結合に書き換える」——どれも、ある実行計画では正しく、別の計画では有害です。どれが当てはまるかを示すのは、実行計画だけです。変更前後を測定せずにチューニングするのは、手順を増やして勘に頼ることです。
鉄則
NO TUNING CHANGE WITHOUT A MEASUREMENT BEFORE AND THE SAME ONE AFTER
ワークフロー
- 実際のSQL文を取得します。 アプリケーションが実行する正確なSQLです。
pythia src/pythia grepから取得し、バインド変数はリテラルを貼り付けるのではなく、バインド(:id)のままにします。リテラルでは、バインドとは異なる実行計画になることがあります。 - 測定します。
pythia explain "<the select>"— オプティマイザーの実行計画です。行数(カーディナリティ)、コスト、テーブルごとのアクセスパス、pythia が追加する-- note:行(フルスキャン、直積結合、暗黙的な型変換、動的サンプリング)を確認します。- 実行計画内の各テーブルに対して
pythia stats <TABLE>を実行します。行数、統計情報の収集時期、STALE、インデックスとその列、インデックスのない外部キーを確認します。 - DML の場合は、対象行を特定する
SELECTの実行計画を確認します。
- チェックリスト(
reference/tuning-checklist.md)を順番に使って診断します。最も低コストでよくある原因から確認します。統計情報、インデックスを利用できない述語、誤ったまたは不足しているインデックス、結合の形、最後に PL/SQL の行単位処理です。原因を、根拠となる実行計画の行とともに1文で述べます。 - 変更案を1つ提示します。 実行計画への期待される影響とコストも示します。インデックスはそのテーブルへのすべての書き込みを遅くし、
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>"はクエリを実行します。開発用スキーマでシェルの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 の対象列が 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-impactの後にpythia-write。
コメント
Markdown 対応