query-optimizer
Comprehensive development toolkit: 52 professional skills for Claude Code across development, code quality, API, database, security, DevOps, data analytics, and collaboration
19 stars4 forksUpdated Oct 20, 2025
npx skills add https://github.com/curiouslearner/devkit --skill query-optimizerSKILL.md
Query Optimizer Skill
Analyze and optimize SQL queries for better performance and efficiency.
Instructions
You are a database performance optimization expert. When invoked:
-
Analyze Query Performance:
- Use EXPLAIN/EXPLAIN ANALYZE to understand execution plan
- Identify slow queries from logs
- Measure query execution time
- Detect full table scans and missing indexes
-
Identify Bottlenecks:
- Find N+1 query problems
- Detect inefficient JOINs
- Identify missing or unused indexes
- Spot suboptimal WHERE clauses
-
Optimize Queries:
- Add appropriate indexes
- Rewrite queries for better performance
- Suggest caching strategies
- Recommend query restructuring
-
Provide Recommendations:
- Index creation suggestions
- Query rewriting alternatives
- Database configuration tuning
- Monitoring and alerting setup
Supported Databases
- SQL: PostgreSQL, MySQL, MariaDB, SQL Server, SQLite
- Analysis Tools: EXPLAIN, EXPLAIN ANALYZE, Query Profiler
- Monitoring: pg_stat_statements, slow query log, performance schema
Usage Examples
@query-optimizer
@query-optimizer --analyze-slow-queries
@query-optimizer --suggest-indexes
@query-optimizer --explain SELECT * FROM users WHERE email = 'test@example.com'
@query-optimizer --fix-n-plus-one
Query Analysis Tools
PostgreSQL - EXPLAIN ANALYZE
-- Basic EXPLAIN
EXPLAIN
SELECT u.id, u.username, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
GROUP BY u.id, u.username;
-- EXPLAIN ANALYZE - actually runs the query
EXPLAIN ANALYZE
SELECT u.id, u.username, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
GROUP BY u.id, u.username;
-- EXPLAIN with all options (PostgreSQL)
EXPLAIN (ANALYZE, BUFFERS, VERBOSE, FORMAT JSON)
SELECT * FROM orders
WHERE user_id = 123
AND created_at >= '2024-01-01';
Reading EXPLAIN Output:
Seq Scan on users (cost=0.00..1234.56 rows=10000 width=32)
Filter: (active = true)
-- Seq Scan = Sequential Scan (full table scan) - BAD for large tables
-- cost=0.00..1234.56 = startup cost..total cost
-- rows=10000 = estimated rows
-- width=32 = average row size in bytes
Index Scan using idx_users_email on users (cost=0.29..8.30 rows=1 width=32)
Index Cond: (email = 'test@example.com'::text)
-- Index Scan = Using index - GOOD
-- Much lower cost than Seq Scan
-- rows=1 = accurate estimate
MySQL - EXPLAIN
-- MySQL EXPLAIN
EXPLAIN
SELECT u.id, u.username, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
GROUP BY u.id, u.username;
-- EXPLAIN with execution stats (MySQL 8.0+)
EXPLAIN ANALYZE
SELECT * FROM orders
WHERE user_id = 123;
-- Show warnings for optimization info
EXPLAIN
SELECT * FROM users WHERE email = 'test@example.com';
SHOW WARNINGS;
MySQL EXPLAIN Output:
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 1000 | Using where |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
-- type=ALL means full table scan - BAD
-- key=NULL means no index used
+----+-------------+-------+------+---------------+----------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------------+---------+-------+------+-------+
| 1 | SIMPLE | users | ref | idx_users_email| idx_users_email| 767 | const | 1 | NULL |
+----+-------------+-------+------+---------------+----------------+---------+-------+------+-------+
-- type=ref means index lookup - GOOD
-- key shows index being used
Common Performance Issues
1. Missing Indexes
Problem:
-- Slow query - full table scan
SELECT * FROM users WHERE email = 'john@example.com';
-- EXPLAIN shows:
-- Seq Scan on users (cost=0.00..1500.00 rows=1 width=100)
-- Filter: (email = 'john@example.com')
Solution:
-- Add index on email column
CREATE INDEX idx_users_email ON users(email);
-- Now EXPLAIN shows:
-- Index Scan using idx_users_email on users (cost=0.29..8.30 rows=1 width=100)
-- Index Cond: (email = 'john@example.com')
-- Query becomes 100x faster
2. N+1 Query Problem
Problem:
// ORM code causing N+1 queries
const users = await User.findAll(); // 1 query
for (const user of users) {
const orders = await Order.findAll({
where: { userId: user.id } // N queries (one per user)
});
console.log(`
...
Repository
curiouslearner/devkitParent repository
Repository Stats
Stars19
Forks4
LicenseMIT License