Claude Skills Guide

Claude Code for Database Query Optimization Workflow

Database query performance can make or break your application. Slow queries frustrate users, increase server load, and can cost significantly in cloud infrastructure expenses. The good news: Claude Code combined with systematic optimization workflows can help you identify, analyze, and fix performance bottlenecks faster than ever.

This guide walks you through a practical workflow for optimizing database queries using Claude Code. You’ll learn how to leverage AI for query analysis, index recommendations, query restructuring, and performance validation—turning what was once a tedious manual process into an efficient, repeatable workflow.

Setting Up Your Query Optimization Environment

Before diving into optimization, ensure your environment is ready. You’ll want a way to explain your database schema to Claude and capture query execution plans.

Start by creating a schema description file. This serves as context for Claude to understand your data model:

-- schema-context.md content example
## Database Schema

### Users Table
- id: UUID, primary key
- email: VARCHAR(255), unique
- created_at: TIMESTAMP
- role: VARCHAR(50)

### Orders Table
- id: UUID, primary key
- user_id: UUID, foreign key -> users.id
- total: DECIMAL(10,2)
- status: VARCHAR(50)
- created_at: TIMESTAMP

### OrderItems Table
- id: UUID, primary key
- order_id: UUID, foreign key -> orders.id
- product_id: UUID
- quantity: INTEGER
- price: DECIMAL(10,2)

Keep this file updated as your schema evolves. Claude uses this context to provide relevant optimization suggestions.

Analyzing Queries with Execution Plans

The foundation of query optimization is understanding how your database executes queries. PostgreSQL’s EXPLAIN and MySQL’s EXPLAIN ANALYZE provide detailed execution plans that reveal bottlenecks.

When you have a slow query, ask Claude to analyze it:

Here's my slow query:
```sql
SELECT o.*, u.email, u.name 
FROM orders o 
JOIN users u ON o.user_id = u.id 
WHERE o.created_at > '2025-01-01' 
AND u.role = 'premium' 
ORDER BY o.created_at DESC 
LIMIT 100;

And here’s the EXPLAIN output: [paste your EXPLAIN ANALYZE output here]

Can you identify the performance issues and suggest optimizations?


Claude can interpret execution plans and explain what each operation means—sequential scans vs index scans, nested loop joins, missing index warnings, and estimated vs actual row counts.

## Common Query Patterns and Their Optimizations

Let's explore frequent optimization scenarios where Claude Code shines.

### Missing Index Optimizations

One of the most common issues is queries filtering or joining on columns without indexes. Claude can spot these patterns:

Review this query and suggest index additions:

SELECT * FROM orders WHERE status = ‘pending’ AND created_at < NOW() - INTERVAL ‘30 days’;


Claude will typically suggest a composite index like `(status, created_at)` based on the WHERE clause order and selectivity.

### N+1 Query Problems

Eager loading prevents the N+1 problem where your application makes one query plus N additional queries for each result. Here's how to address it:

Current implementation fetches orders then loops through each to get items:

Ruby/Rails example

orders = Order.where(user_id: user.id).all orders.each do |order| items = OrderItem.where(order_id: order.id).all # N+1! # process items end

How can I rewrite this to use eager loading?


Claude responds with optimized code using your framework's eager loading methods—`includes` in Rails, `joinedload` in SQLAlchemy, or explicit JOINs.

### Covering Indexes for Read Performance

When queries read columns included in an index, the database can satisfy the query entirely from the index without touching table data:

This query runs frequently: SELECT id, email, name FROM users WHERE email = ‘user@example.com’;

What covering index would optimize this, and why?


Claude explains how a covering index `(email, id, name)` allows index-only scans, reducing I/O operations.

## Building an Optimization Workflow

Transform query optimization from ad-hoc fixes into a systematic process:

### Step 1: Identify Slow Queries

Use database logs, monitoring tools, or ORM query logging to find problematic queries. In PostgreSQL:

```sql
-- Enable query timing
\timing on

-- Or use pg_stat_statements
SELECT query, calls, total_exec_time, mean_exec_time 
FROM pg_stat_statements 
ORDER BY total_exec_time DESC 
LIMIT 10;

Step 2: Capture Execution Plans

Run EXPLAIN ANALYZE (not just EXPLAIN) to see actual execution times and row counts:

EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) 
SELECT your_query_here;

Step 3: Analyze with Claude

Paste the query and EXPLAIN output to Claude with specific questions:

Step 4: Implement and Validate

Apply suggestions one at a time, re-running EXPLAIN ANALYZE after each change to measure impact.

Step 5: Document Patterns

Create a reference document of optimization patterns discovered in your codebase. Claude can help generate this:

Create a markdown document summarizing common query patterns in our app 
and their optimized versions based on our previous optimizations.

Actionable Optimization Tips

Here are concrete takeaways to apply immediately:

Index Strategically

Optimize Query Structure

Leverage Caching Wisely

Monitor Continuously

Conclusion

Database query optimization doesn’t have to be a painful manual process. By combining Claude Code’s analytical capabilities with systematic workflows, you can identify bottlenecks faster, implement better solutions, and maintain query performance as your application scales.

Start by documenting your schema, capturing execution plans for slow queries, and using Claude to interpret results and suggest optimizations. Build these practices into your development workflow, and you’ll catch performance issues before they reach production.

Remember: optimization is iterative. Measure, improve, measure again—and let Claude help you understand the “why” behind each optimization. Your users (and your cloud bill) will thank you.