data-sql について
開発者やデータ担当者向けの、SQLの記述と設計を支援するスキルです。PostgreSQL、Redshift、Athena、Spark SQLを対象に、クエリ構成、スキーマ設計、インデックスを意識した性能改善を扱います。
主な機能
- 01CTEによるクエリ構成
- 02早期フィルタリングと列の明示
- 03インデックスを意識したクエリパターン
- 04スキーマ設計と正規化
- 05ウィンドウ関数とデータモデリング
- 06冪等なupsertの指針
活用シーン
- 01本番SQLクエリの最適化
- 02スキーマとデータモデルの設計
- 03CTEによる複雑なクエリの整理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ alexanderstephenthompson/ claude-hub --skill data-sqlインストール後、Claude Code で/data-sqlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/query-patterns.mdreferences/window-functions.mdquery-optimization.md詳細
データ SQL スキル
バージョン: 1.0 スタック: SQL(PostgreSQL、Redshift、Athena、Spark SQL)
SQL は、同じように動作するクエリでも、実行速度が 1,000 倍遅くなることがある唯一の言語です。インデックスがないと、50 ms の検索が 50 秒のフルテーブルスキャンに変わります。SELECT * は、誰かが列を追加したときに後続のコードを壊します。相関サブクエリは、開発環境では気づかれず、本番環境を圧迫する N+1 パターンをひそかに実行します。クエリプランナーは警告しません。ただ、指示されたとおりに実行するだけです。
インデックスを意識し、列を明示し、CTE を使って記述した SQL は、実行が速く、デバッグも容易です。明瞭さとパフォーマンスは互いを高めます。
対象範囲と境界
このスキルで扱う内容:
- クエリ最適化のパターン
- スキーマ設計と正規化
- データモデリング(スター・スキーマ、緩やかに変化するディメンション)
- CTE とクエリの構成
- インデックス戦略
- ウィンドウ関数
他のスキルに委ねる内容:
security:SQL インジェクション対策、パラメーター化クエリdata-pipelines:SQL とアプリケーションコードのどちらを使うか
このスキルを使う場面: SQL クエリを記述するとき、またはスキーマを設計するとき。
基本原則
- 読みやすさのための CTE — 複雑なクエリを名前付きのステップに分割します。
- 早期に絞り込む — WHERE 句をできるだけデータソースに近い位置に適用します。
- 列を明示する — 本番コードでは
SELECT *を使いません。 - インデックスを意識したクエリ — どの列にインデックスがあるかを把握し、それを利用するクエリを記述します。
- 冪等な操作 — INSERT/UPDATE は安全に再試行できるようにします。
パターン
CTE の構成
-- Good - logical steps, easy to debug
WITH active_users AS (
SELECT user_id, email
FROM users
WHERE status = 'active'
),
recent_orders AS (
SELECT user_id, COUNT(*) as order_count
FROM orders
WHERE created_at > CURRENT_DATE - INTERVAL '30 days'
GROUP BY user_id
)
SELECT
u.email,
COALESCE(o.order_count, 0) as recent_orders
FROM active_users u
LEFT JOIN recent_orders o USING (user_id);
Upsert パターン(PostgreSQL)
INSERT INTO inventory (sku, quantity, updated_at)
VALUES ('ABC123', 100, NOW())
ON CONFLICT (sku) DO UPDATE SET
quantity = EXCLUDED.quantity,
updated_at = EXCLUDED.updated_at;
ウィンドウ関数
-- Running total and row number
SELECT
date,
revenue,
SUM(revenue) OVER (ORDER BY date) as running_total,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY revenue DESC) as rank
FROM daily_sales;
アンチパターン
| アンチパターン | 問題 | 修正方法 |
|---|---|---|
SELECT * | スキーマの変更で壊れ、帯域幅を浪費します | 列を明示的に列挙します |
| 相関サブクエリ | N+1 クエリの動作 | JOIN またはウィンドウ関数を使います |
JOIN 条件での OR | インデックスを利用できません | 構造を変更するか、UNION を使います |
| インデックス付き列に対する関数 | WHERE YEAR(date) = 2024 | 範囲指定を使います:date >= '2024-01-01' |
GROUP BY 列の不足 | 動作が未定義になります | 集約されない列をすべて含めます |
チェックリスト
- 本番クエリで
SELECT *を使っていない - 複雑なクエリで CTE を使用している
- WHERE 句で早期に絞り込んでいる
- JOIN ではインデックス付きの列を優先している
- Upsert が冪等である
- 大規模なクエリを EXPLAIN でテストしている
参考資料
references/query-optimization.md— インデックスの使用、JOIN の最適化、パフォーマンスreferences/window-functions.md— ウィンドウ関数のパターンと例
アセット
assets/query-patterns.md— 一般的な SQL パターンとテンプレート
コメント
Markdown 対応