Database performance tuning: index analysis, query plan optimization, connection pooling, and configuration tuning.
"A slow query is a bug. Treat it like one."
Invoked when database queries are identified as bottlenecks, or proactively during performance reviews.
Steps:
Steps:
EXPLAIN ANALYZE on each slow query.Steps:
CREATE INDEX / DROP INDEX migration files.Steps:
pool_size = (2 * cpu_cores) + disk_spindles.| Field | Type | Description |
|---|---|---|
slow_queries | object[] | Top slow queries with analysis |
index_changes | string[] | Migration files for index changes |
pool_config | object | Connection pool recommendations |
EXPLAIN ANALYZE.database-design).caching-strategy).migration-planning).data-access).DROP INDEX on production without verifying the index is unused for at least 7 days.max_connections or memory parameters without documenting the rationale and rollback values.EXPLAIN ANALYZE on non-production data or read replicas to avoid impacting live traffic.{table_name}?"max_connections setting and peak concurrent connection count?"| Situation | Action |
|---|---|
| Sequential scan on table with > 10k rows in a frequent query | Add a B-tree index on the filtered/joined column |
Query uses ORDER BY on a non-indexed column with LIMIT | Add an index matching the sort order to enable index-scan |
| Composite index covers a subset of an existing broader index | Drop the narrower redundant index |
Index exists but pg_stat_user_indexes.idx_scan = 0 for 30+ days | Recommend dropping the unused index |
| N+1 pattern detected at DB level (nested loop with high rows) | Rewrite query to use JOIN or batch IN(...) clause |
work_mem too low causing disk-based sorts | Increase work_mem within available RAM budget |
| Pool exhaustion errors under load | Increase pool max; verify it stays below DB max_connections |
| Query plan changes after data growth | Add ANALYZE to maintenance schedule; consider partial indexes |
EXPLAIN ANALYZE.| Failure | Symptom | Mitigation |
|---|---|---|
| Index bloat from over-indexing | Write latency increases; storage grows disproportionately | Limit indexes per table; audit unused indexes quarterly |
| Lock contention during index creation | Application timeouts during migration | Use CREATE INDEX CONCURRENTLY (PostgreSQL) or online DDL equivalents |
| Wrong index type selected | Query plan ignores the new index; no performance gain | Verify index type matches query pattern (B-tree vs. GIN vs. hash) |
| Connection pool too large | DB runs out of memory; max_connections exceeded | Size pool to (2 × CPU cores) + spindles; monitor active vs. idle connections |
| Query rewrite changes semantics | Different result set returned after optimization | Diff query outputs before and after rewrite; run integration tests |
| Parameter tuning causes instability | OOM kills, checkpoint spikes, or replication lag | Change one parameter at a time; document rollback values; monitor for 24h |
Missing ANALYZE after bulk load | Planner uses stale statistics; regression in query plans | Schedule ANALYZE after large data loads; automate with maintenance jobs |
Each invocation of the Database Tuning skill records the following timestamped entries in the scratchpad:
[YYYY-MM-DDTHH:MM:SSZ] DB_TUNING_START — Skill invoked; target database and tables noted.[YYYY-MM-DDTHH:MM:SSZ] SLOW_QUERIES_COLLECTED — Top N slow queries identified with frequency and duration.[YYYY-MM-DDTHH:MM:SSZ] EXPLAIN_ANALYSIS — EXPLAIN ANALYZE results captured for each slow query.[YYYY-MM-DDTHH:MM:SSZ] INDEX_RECOMMENDATIONS — Proposed index additions/removals with rationale.[YYYY-MM-DDTHH:MM:SSZ] MIGRATIONS_GENERATED — Migration files created; file paths listed.[YYYY-MM-DDTHH:MM:SSZ] POOL_CONFIG_REVIEWED — Connection pool settings evaluated; recommendations documented.[YYYY-MM-DDTHH:MM:SSZ] TESTS_PASSED — Test suite executed post-change; pass/fail status recorded.[YYYY-MM-DDTHH:MM:SSZ] DB_TUNING_END — Skill completed; before/after query latency comparison logged.