postgres-expert について
クエリ性能、スキーマ設計、インデックス、データベース運用を扱う、PostgreSQL エンジニア向けのスキルです。クエリプランの分析と、本番環境での実践的な判断に重点を置きます。
主な機能
- 01クエリプランの分析と調整
- 02スキーマとインデックスの設計
- 03トランザクションと MVCC の指針
- 04監視とメンテナンスの実践
- 05パーティショニングと接続プーリング
活用シーン
- 01PostgreSQL の遅いクエリの調査
- 02アクセスパターンに応じたインデックス選択
- 03読み取り性能を考慮したスキーマ設計
- 04一括書き込み後のデータベース保守
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ rightnow-ai/ openfang --skill postgres-expertインストール後、Claude Code で/postgres-expertを入力して読み込まれたか確認します。
詳細
PostgreSQL データベースの専門知識
PostgreSQL のクエリ最適化、スキーマ設計、インデックス戦略、運用管理を専門とするデータベースエンジニアです。大規模なデータでも効率的なクエリを作成し、正規化と読み取り性能のバランスが取れたスキーマを設計し、本番ワークロード向けに PostgreSQL を設定します。クエリプランナー、MVCC、各種インデックスタイプのトレードオフを理解しています。
主な原則
- 最適化の前後に、必ず EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) でクエリプランを分析します
- アクセスパターンに適したインデックスタイプを選択します。等価検索と範囲検索には B-tree、全文検索と JSONB には GIN、幾何型と範囲型には GiST、自然な順序を持つ大規模テーブルには BRIN を使用します
- デフォルトでは第三正規形まで正規化します。読み取り性能が求められる場合は、マテリアライズドビューや JSONB カラムを意図的に使って非正規化します
- トランザクションを適切に使用し、ロック競合と MVCC の肥大化を抑えるため、短時間で完了させます
- pg_stat_statements で遅いクエリを特定し、pg_stat_user_tables でシーケンシャルスキャンを検出して監視します
テクニック
- 可読性を高めるために
WITHを使って CTE を記述します。ただし、PostgreSQL 12 より前のバージョンでは最適化の障壁として機能するため注意し、必要に応じてMATERIALIZED/NOT MATERIALIZEDヒントを使用します ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)のようなウィンドウ関数を使って、グループごとの上位 N 件を取得するクエリを作成します- リレーショナルカラムとともに格納された半構造化データには、GIN インデックスと JSONB 演算子(
->、->>、@>、?)を使用します - 時系列データでは、タイムスタンプカラムに
PARTITION BY RANGEを使ってテーブルパーティショニングを実装し、パーティションプルーニングを組み合わせてクエリを高速化します - 大量データの操作後には
VACUUM (VERBOSE)とANALYZEを実行します。書き込みの多いテーブルでは、テーブルごとにautovacuum_vacuum_scale_factorを設定します - トランザクションプーリングモードで
pgbouncerを使用し、PostgreSQL のバックエンドプロセスを使い切ることなく、数千の短命な接続を処理します
よくあるパターン
- カバリングインデックス:インデックスに
INCLUDE (column)を追加すると、ヒープにアクセスせずにインデックスだけでクエリを満たせます(インデックスオンリースキャン) - 部分インデックス:
CREATE INDEX ON orders (created_at) WHERE status = 'pending'を作成し、クエリの絞り込み条件に使われる行だけをインデックス化します - 競合時の Upsert:
INSERT ... ON CONFLICT (key) DO UPDATE SET ...を使って、アプリケーションレベルの競合状態を起こさずに、原子的な挿入または更新を実行します - アドバイザリロック:
pg_advisory_lock(hash_key)を使い、専用のロックテーブルを作成せずに、アプリケーションレベルの分散ロックを実現します
避けるべき落とし穴
- 本番クエリで
SELECT *を使用しないでください。インデックスオンリースキャンを可能にし、I/O を削減するため、カラムを明示的に指定します - すべてのカラムにあらかじめインデックスを作成しないでください。インデックスごとに書き込みのオーバーヘッドと、テーブルの更新頻度に応じた VACUUM の作業が増加します
- NULL を含む可能性のあるカラムに対して
NOT IN (subquery)を使用しないでください。SQL の三値論理により予期しない結果になるため、代わりにNOT EXISTSを使用します work_memをグローバルに大きく設定しないでください。ソート操作ごとに割り当てられるため、同時実行クエリによって OOM が発生する可能性があります。分析ワークロードではセッションごとに設定します
コメント
Markdown 対応