Postgres Optimization
PostgreSQL optimization including indexes, query plans, partitioning, JSONB operations...
Install
npx skills add rohitg00/awesome-claude-code-toolkit --skill postgres-optimization -g -a claude-code -y- Repository
- rohitg00/awesome-claude-code-toolkit2.8k
- Category
- Engineering
- Updated
- 6mo ago
- License
- Apache-2.0
- Context cost
- Lightabout 1,081 tokens
- Runs scripts
- No, instructions only
What it does
PostgreSQL optimization including indexes, query plans, partitioning, JSONB operations, and connection pooling
PostgreSQL Optimization
Index Strategies
-- B-tree index for equality and range queries (default)
CREATE INDEX idx_orders_customer_id ON orders (customer_id);
-- Composite index (column order matters: equality columns first, range last)
CREATE INDEX idx_orders_status_created ON orders (status, created_at DESC);
-- Partial index (smaller, faster for filtered queries)
CREATE INDEX idx_orders_pending ON orders (created_at)
WHERE status = 'pending';
-- Covering index (avoids table lookup entirely)
CREATE INDEX idx_users_email_name ON users (email) INCLUDE (name, avatar_url);
-- GIN index for JSONB containment queries
CREATE INDEX idx_products_metadata ON products USING GIN (metadata);
-- GiST index for full-text search
CREATE INDEX idx_articles_search ON articles USING GiST (
to_tsvector('english', title || ' ' || body)
);
-- Concurrent index creation (no table lock)
CREATE INDEX CONCURRENTLY idx_large_table_col ON large_table (col);
Reading Query Plans
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT o.id, o.total, u.name
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.status = 'shipped'
AND o.created_at > NOW() - INTERVAL '30 days'
ORDER BY o.created_at DESC
LIMIT 20;
Key things to look for in the plan:
Seq Scanon large tables indicates a missing indexNested Loopwith high row estimates suggests missing join indexSortwithoutIndex Scanmeans the sort is happening in memory/diskBuffers: shared hitvsshared readshows cache efficiency
Partitioning
CREATE TABLE events (
id BIGINT GENERATED ALWAYS AS IDENTITY,
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
) PARTITION BY RANGE (created_at);
CREATE TABLE events_2024_q1 PARTITION OF events
FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');
CREATE TABLE events_2024_q2 PARTITION OF events
FOR VALUES FROM ('2024-04-01') TO ('2024-07-01');
