Claude-skill-registry data-analyst-sql-optimization
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/data-analyst-sql-optimization" ~/.claude/skills/majiayu000-claude-skill-registry-data-analyst-sql-optimization && rm -rf "$T"
skills/data/data-analyst-sql-optimization/SKILL.mdData Analyst SQL Optimization Skill
概要
このSkillは、data-analystエージェントがSQLクエリのパフォーマンスを改善する際に使用します。実績のある最適化パターンとベストプラクティスを提供し、遅いクエリを高速化します。
主な機能
- 最適化パターンライブラリ: 頻出の最適化パターンをカタログ化
- Before/After例: 実際の改善例を多数掲載
- インデックス推奨: 適切なインデックス戦略の提案
- 実行計画解析ガイド: EXPLAINの読み方と改善点の特定
使用方法
基本的な使い方
- 遅いクエリを特定: クエリ実行時間をログで確認
- 該当する最適化パターンを探す: reference.mdから適用可能なパターンを選択
- クエリを書き換え: パターンに従ってクエリを最適化
- 実行計画で検証: EXPLAINで改善を確認
- パフォーマンス測定: 実行時間の短縮を確認
トリガーキーワード
以下のキーワードを含むユーザーリクエストで自動起動されます:
- "optimize SQL" / "SQL最適化"
- "slow query" / "遅いクエリ"
- "improve performance" / "パフォーマンス向上"
- "query tuning" / "クエリチューニング"
最適化パターン一覧
1. N+1クエリ削減
問題: ループ内で繰り返しSELECT文を実行 解決: JOINまたはサブクエリで1回のクエリに統合
2. インデックス活用
問題: WHERE句の列にインデックスがない 解決: 適切なインデックスを作成
3. JOIN最適化
問題: 不要な大規模テーブルのJOIN 解決: 必要な列のみ取得、結合順序の最適化
4. ウィンドウ関数活用
問題: 複雑なサブクエリの入れ子 解決: ROW_NUMBER(), RANK()等のウィンドウ関数を使用
5. DISTINCT削減
問題: 不要なDISTINCT使用 解決: GROUP BYまたは適切なJOINで代替
6. EXISTS vs IN
問題: サブクエリでINを使用 解決: EXISTSに変更(多くの場合高速)
7. LIMIT活用
問題: 全件取得後にアプリ側でフィルタ 解決: SQLでLIMIT/OFFSETを使用
8. 計算列のインデックス
問題: WHERE句で関数を列に適用 解決: 計算済み列を作成してインデックス
リファレンス
詳細な最適化パターンとコード例は、以下のファイルを参照してください:
: 各パターンの詳細説明reference.md
: Before/Afterの実例examples.md
実装例
例1: N+1クエリの削減
Before:
-- ループで実行(N+1クエリ) SELECT * FROM users WHERE id = ?; -- N回実行
After:
-- 1回のクエリで取得 SELECT u.*, o.order_count FROM users u LEFT JOIN ( SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id ) o ON u.id = o.user_id;
改善: N+1回 → 1回のクエリ、大幅な高速化
例2: インデックス活用
Before:
SELECT * FROM orders WHERE created_at > '2023-01-01' AND status = 'completed'; -- インデックスなし、フルスキャン
After:
-- インデックス作成 CREATE INDEX idx_orders_status_created ON orders(status, created_at); -- 同じクエリがインデックスを使用 SELECT * FROM orders WHERE status = 'completed' AND created_at > '2023-01-01'; -- ORDER BY の順序を逆にしてインデックス効率化
改善: フルスキャン → インデックススキャン、10倍以上高速化
例3: ウィンドウ関数活用
Before:
-- サブクエリの入れ子 SELECT u.name, (SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) as order_count, (SELECT SUM(total) FROM orders o WHERE o.user_id = u.id) as order_total FROM users u; -- usersの各行でordersを2回スキャン
After:
-- ウィンドウ関数で1回のスキャン SELECT u.name, COUNT(o.id) OVER (PARTITION BY u.id) as order_count, SUM(o.total) OVER (PARTITION BY u.id) as order_total FROM users u LEFT JOIN orders o ON u.id = o.user_id; -- 1回のJOINで完結
改善: 2N回スキャン → 1回のJOIN、大幅な高速化
ベストプラクティス
DO(推奨)
✅ EXPLAINで実行計画を確認: 最適化前後で必ず確認 ✅ インデックスは選択的に作成: WHERE/JOIN/ORDER BYで使用される列 ✅ 必要な列のみSELECT: SELECT *は避ける ✅ 早期フィルタリング: WHERE句を最初に適用 ✅ 統計情報を更新: ANALYZE TABLEで最新状態に
DON'T(非推奨)
❌ 不要なDISTINCT: データ構造を見直す ❌ 関数をWHERE句の列に適用: インデックスが使用されない ❌ 過剰なJOIN: 必要最小限に絞る ❌ サブクエリの多用: JOINやウィンドウ関数で代替 ❌ インデックスの作り過ぎ: INSERT/UPDATEが遅くなる
パフォーマンス測定
改善前後の比較
-
実行時間測定:
-- BigQueryの場合 SELECT CURRENT_TIMESTAMP(); -- クエリ実行 SELECT CURRENT_TIMESTAMP(); -
スキャンバイト数確認:
- BigQuery: クエリ結果に表示
- 改善後は大幅に削減されるはず
-
実行計画比較:
EXPLAIN SELECT ...;
目標指標
- 実行時間: 50%以上削減
- スキャンバイト数: 70%以上削減(BigQuery)
- インデックス使用: EXPLAINでtype=ref以上
トラブルシューティング
Q: 最適化したのに遅い
A: 以下を確認:
- インデックスが実際に使用されているか(EXPLAIN確認)
- 統計情報が最新か(ANALYZE TABLE実行)
- データ量が想定通りか
Q: どのパターンを適用すべきか分からない
A: 以下の順で確認:
- EXPLAINで実行計画を確認
- フルスキャンがあればインデックス作成
- N+1パターンがあればJOINに統合
- サブクエリが複雑ならウィンドウ関数検討
Q: インデックスを作成したら書き込みが遅くなった
A: インデックスの見直しが必要:
- 使用頻度の低いインデックスを削除
- 複合インデックスで統合できないか検討
Progressive Disclosure
このSKILL.mdはメインドキュメント(約200行)です。詳細な最適化パターンとコード例は別ファイル(reference.md, examples.md)に分離されています。
関連リソース
- reference.md: 最適化パターン詳細リファレンス
- examples.md: Before/After実例集
- BigQuery公式ドキュメント: ベストプラクティス