Agent skill
database-performance
Analyze and optimize database performance through index analysis and query profiling. Identify missing/unused indexes, interpret EXPLAIN plans, find performance bottlenecks, and recommend optimization strategies. Use when optimizing slow queries, analyzing database workloads, improving query execution speed, or managing database indexes.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/database-performance
SKILL.md
Database Performance Optimization
Comprehensive database performance analysis covering index optimization and query profiling to enhance database speed and efficiency.
Overview
This skill empowers you to:
- Analyze database indexes: Identify missing indexes for better performance and unused indexes for removal
- Profile query performance: Interpret EXPLAIN plans, find bottlenecks, and optimize query execution
- Recommend optimizations: Provide actionable strategies for index creation, query rewriting, and configuration tuning
Part 1: Index Analysis
How It Works
- Workload Analysis: Analyze database query patterns and existing index configurations
- Missing Index Detection: Identify queries that would benefit from additional indexes
- Unused Index Detection: Find indexes that are never used and can be safely removed
- Recommendation Generation: Provide specific index creation/removal suggestions
When to Use Index Analysis
- Optimize slow-running queries
- Identify performance bottlenecks related to missing indexes
- Reclaim storage space by removing unused indexes
- Plan index strategy for new tables
- Audit existing index configurations
Index Analysis Examples
Example 1: Optimizing a Slow Query
User request: "My orders table query is running slowly. Can you help optimize it?"
Analysis Process:
- Examine the query:
SELECT * FROM orders WHERE customer_id = 123 AND status = 'pending' - Check existing indexes on orders table
- Identify missing composite index on
(customer_id, status) - Recommendation:
sql
CREATE INDEX idx_orders_customer_status ON orders(customer_id, status);
Example 2: Identifying Unused Indexes
User request: "Can you help me identify and remove any unused indexes in my database?"
Analysis Process:
- Query database statistics for index usage
- Identify indexes with zero reads
- Verify these indexes aren't required for constraints
- Recommendation:
sql
-- Indexes with 0 usage in last 30 days DROP INDEX idx_old_column ON users; DROP INDEX idx_rarely_used ON orders;
Index Best Practices
✅ DO:
- Create indexes on columns frequently used in WHERE clauses
- Use composite indexes for queries filtering on multiple columns
- Index foreign keys for faster JOIN operations
- Monitor index usage regularly
- Remove unused indexes to improve write performance
❌ DON'T:
- Over-index tables (each index slows down writes)
- Create duplicate indexes (e.g.,
(a)and(a, b)) - Index low-cardinality columns (e.g., boolean fields)
- Forget to analyze impact before dropping indexes
Part 2: Query Performance Analysis
How It Works
- Receive Input: User provides EXPLAIN plan, slow query, or performance problem description
- Analyze Metrics: Examine execution plan, identify full table scans, join inefficiencies, missing indexes
- Bottleneck Detection: Pinpoint specific performance issues (I/O, CPU, memory)
- Provide Solutions: Suggest query rewrites, new indexes, or configuration changes
When to Use Query Analysis
- Analyze EXPLAIN plans of slow queries
- Identify performance bottlenecks in complex queries
- Optimize JOIN operations
- Reduce query execution time
- Understand database resource utilization
Query Analysis Examples
Example 1: Analyzing a Slow Query with EXPLAIN
User request: "Here's the EXPLAIN plan for my slow query. Can you help me optimize it?"
EXPLAIN SELECT o.*, u.name
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.status = 'pending' AND o.created_at > '2025-01-01';
EXPLAIN Output:
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 5000 | Using where |
| 1 | SIMPLE | u | ref | PRIMARY | PRIMARY | 4 | o.user_id | 1 | |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
Analysis:
- ⚠️ Issue 1: Full table scan on
orders(type: ALL, rows: 5000) - ⚠️ Issue 2: No index on
statusorcreated_atcolumns - ✅ Good: Efficient JOIN on
usersusing PRIMARY key
Recommendations:
-- Create composite index for WHERE clause
CREATE INDEX idx_orders_status_created ON orders(status, created_at);
-- After creating index, EXPLAIN shows:
-- type: range (instead of ALL)
-- rows: 150 (instead of 5000)
-- 97% reduction in rows scanned!
Example 2: Optimizing Complex JOIN
User request: "My query with multiple JOINs is very slow. What could be the problem?"
Original Query:
SELECT p.*, c.name as category, u.name as author
FROM posts p
LEFT JOIN categories c ON p.category_id = c.id
LEFT JOIN users u ON p.user_id = u.id
WHERE p.published = 1
ORDER BY p.created_at DESC
LIMIT 20;
Analysis:
- Check if foreign keys (
category_id,user_id) are indexed - Verify
publishedcolumn has index - Check if
created_atis indexed for ORDER BY
Recommendations:
-- Add indexes for JOIN and WHERE
CREATE INDEX idx_posts_published ON posts(published);
CREATE INDEX idx_posts_category ON posts(category_id);
CREATE INDEX idx_posts_user ON posts(user_id);
-- Add compound index for WHERE + ORDER BY
CREATE INDEX idx_posts_pub_created ON posts(published, created_at DESC);
Example 3: Fixing N+1 Query Problem
User request: "My application is making too many queries. How do I fix this?"
Problem:
# N+1 Problem: 1 query + N queries (if 100 posts = 101 queries!)
posts = Post.all() # 1 query
for post in posts:
print(post.author.name) # N queries (1 per post)
Solution:
# Use eager loading: Only 2 queries total
posts = Post.select_related('author').all() # 1 query with JOIN
for post in posts:
print(post.author.name) # No additional queries!
Query Optimization Techniques
1. Use Proper Indexes
-- Before: Full table scan
SELECT * FROM orders WHERE customer_id = 123;
-- After: Index seek
CREATE INDEX idx_customer ON orders(customer_id);
**2. Avoid SELECT ***
-- ❌ Bad: Retrieves all columns (slower)
SELECT * FROM users WHERE id = 1;
-- ✅ Good: Only needed columns
SELECT id, name, email FROM users WHERE id = 1;
3. Use LIMIT for Large Results
-- ❌ Bad: Returns millions of rows
SELECT * FROM logs WHERE created_at > '2025-01-01';
-- ✅ Good: Paginate results
SELECT * FROM logs WHERE created_at > '2025-01-01' LIMIT 1000 OFFSET 0;
4. Optimize Subqueries
-- ❌ Bad: Correlated subquery (runs N times)
SELECT * FROM users WHERE id IN (
SELECT DISTINCT user_id FROM orders WHERE total > 1000
);
-- ✅ Good: JOIN (runs once)
SELECT DISTINCT u.*
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.total > 1000;
5. Use EXPLAIN to Verify
-- Always verify your optimization
EXPLAIN SELECT ...;
-- Look for:
-- - type: Should be 'ref' or 'range', not 'ALL'
-- - rows: Lower is better
-- - Extra: Avoid 'Using filesort' or 'Using temporary'
Common Performance Bottlenecks
1. Missing Indexes
Symptom: Full table scans (EXPLAIN shows type: ALL)
Solution: Create indexes on WHERE, JOIN, and ORDER BY columns
2. Inefficient JOINs
Symptom: Large number of rows examined
Solution: Ensure foreign keys are indexed, use proper JOIN types
3. N+1 Queries
Symptom: Multiple queries in loops
Solution: Use eager loading (JOIN, select_related, includes)
4. Large Result Sets
Symptom: Slow queries returning thousands of rows
Solution: Implement pagination with LIMIT/OFFSET or cursors
5. Complex Subqueries
Symptom: Nested queries causing multiple table scans
Solution: Rewrite as JOINs or CTEs (Common Table Expressions)
6. Unused Indexes
Symptom: Slow writes, wasted storage
Solution: Identify and remove indexes with zero usage
7. Missing Query Cache
Symptom: Repeated identical queries
Solution: Implement application-level caching (Redis, Memcached)
Performance Analysis Tools
PostgreSQL
-- Enable query timing
\timing on
-- Analyze query plan
EXPLAIN ANALYZE SELECT ...;
-- Check index usage
SELECT schemaname, tablename, indexname, idx_scan
FROM pg_stat_user_indexes
ORDER BY idx_scan ASC;
MySQL
-- Enable profiling
SET profiling = 1;
-- Run query
SELECT ...;
-- Show profile
SHOW PROFILES;
SHOW PROFILE FOR QUERY 1;
-- Check unused indexes
SELECT * FROM sys.schema_unused_indexes;
SQL Server
-- Show execution plan
SET SHOWPLAN_ALL ON;
GO
SELECT ...;
GO
-- Find missing indexes
SELECT * FROM sys.dm_db_missing_index_details;
-- Find unused indexes
SELECT * FROM sys.dm_db_index_usage_stats
WHERE user_seeks = 0 AND user_scans = 0;
Best Practices Summary
Index Management
- ✅ Index WHERE, JOIN, ORDER BY columns
- ✅ Use composite indexes for multi-column queries
- ✅ Monitor index usage regularly
- ✅ Remove unused indexes
- ❌ Don't over-index (slows writes)
- ❌ Don't index low-cardinality columns
Query Optimization
- ✅ Use EXPLAIN to analyze queries
- ✅ Avoid SELECT * (fetch only needed columns)
- ✅ Use LIMIT for pagination
- ✅ Optimize JOINs with proper indexes
- ✅ Implement eager loading to avoid N+1
- ❌ Don't use correlated subqueries
- ❌ Don't forget to test optimizations
Performance Monitoring
- ✅ Track slow query logs
- ✅ Monitor database metrics (CPU, I/O, memory)
- ✅ Set up alerts for slow queries
- ✅ Review query performance regularly
- ✅ Benchmark before and after changes
Integration with Other Tools
- Database Monitoring: Integrate with New Relic, Datadog, or AppDynamics
- Query Logging: Use slow query logs to identify problematic queries
- Schema Design: Combine with schema design tools for optimal table structure
- ORM Integration: Work with ORMs to understand generated queries
- Load Testing: Use with load testing tools to find performance limits
Remember: Database performance is iterative. Measure, optimize, and verify improvements with EXPLAIN and real-world metrics.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?