prisma-query-optimizer
npx machina-cli add skill Nembie/claude-code-skills/prisma-query-optimizer --openclawPrisma Query Optimizer
Before generating any output, read config/defaults.md and adapt all patterns, imports, and code examples to the user's configured stack.
Analysis Process
- Locate all Prisma query calls in the specified files or project
- For each query, check for the issues listed below
- Output a structured report with findings and fixes
Issues to Detect
N+1 Queries
Look for loops that execute Prisma queries inside:
// BAD: N+1 query
const users = await prisma.user.findMany();
for (const user of users) {
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
}
// FIX: Use include
const users = await prisma.user.findMany({
include: { posts: true }
});
Missing Eager Loading
Detect when related data is accessed after the initial query without being included:
// BAD: Lazy loading triggers additional queries
const user = await prisma.user.findUnique({ where: { id } });
console.log(user.posts); // undefined or triggers additional query
// FIX: Include related data upfront
const user = await prisma.user.findUnique({
where: { id },
include: { posts: true }
});
Missing Index Hints
Flag queries filtering on fields that likely need indexes:
- Foreign keys used in
whereclauses - Fields used in
orderBy - Fields used in unique lookups without
@unique
Suggest adding indexes in schema.prisma:
model Post {
authorId Int
author User @relation(fields: [authorId], references: [id])
@@index([authorId]) // Add this
}
Redundant Queries
Identify duplicate queries that fetch the same data multiple times in a request:
// BAD: Same query twice
const user1 = await prisma.user.findUnique({ where: { id } });
// ... later in same function
const user2 = await prisma.user.findUnique({ where: { id } });
// FIX: Reuse the result
const user = await prisma.user.findUnique({ where: { id } });
// Use 'user' throughout
Unnecessary Select/Include Combinations
Detect overly broad data fetching:
// BAD: Fetching everything when only name is needed
const users = await prisma.user.findMany({
include: { posts: true, comments: true, profile: true }
});
const names = users.map(u => u.name);
// FIX: Select only what's needed
const users = await prisma.user.findMany({
select: { name: true }
});
Missing Pagination
Flag findMany without take/skip on large tables:
// BAD: Unbounded query
const allPosts = await prisma.post.findMany();
// FIX: Add pagination
const posts = await prisma.post.findMany({
take: 20,
skip: page * 20,
orderBy: { createdAt: 'desc' }
});
Inefficient Counting
Detect full fetches when only count is needed:
// BAD: Fetching all records to count
const posts = await prisma.post.findMany({ where: { published: true } });
const count = posts.length;
// FIX: Use count
const count = await prisma.post.count({ where: { published: true } });
Output Format
Present findings in this structure:
## Prisma Query Analysis
### Critical Issues
- **N+1 Query** in `src/services/user.ts:45`
- Issue: Loop executes individual post queries for each user
- Fix: [code block with corrected query]
### Warnings
- **Missing Index** in `schema.prisma`
- Issue: `Post.authorId` used in queries but not indexed
- Fix: Add `@@index([authorId])` to Post model
### Suggestions
- **Over-fetching** in `src/api/users.ts:23`
- Issue: Including all relations when only user name is used
- Fix: [code block with select]
### Summary
- Critical: X issues
- Warnings: X issues
- Suggestions: X issues
Reference
See references/patterns.md for additional optimization patterns and advanced techniques.
Source
git clone https://github.com/Nembie/claude-code-skills/blob/main/skills/prisma-query-optimizer/SKILL.mdView on GitHub Overview
Analyzes Prisma queries across your project to surface performance issues and provide actionable fixes. It detects issues like N+1 queries, missing eager loading, missing index hints, redundant queries, and missing pagination, then outputs a structured report you can apply to improve database efficiency.
How This Skill Works
The tool reads config/defaults.md to adapt patterns, imports, and code examples to your stack. It then scans the specified files or project for Prisma query calls, flags issues such as N+1 queries, missing includes, missing indexes, redundant queries, and unpaginated finds, and finally returns a structured report with findings and recommended fixes.
When to Use It
- When you need to optimize slow Prisma queries in a project
- When auditing a codebase for Prisma performance bottlenecks
- When reviewing data access patterns for N+1 or lazy loading risks
- When preparing a Prisma migration and considering indexing strategies
- When validating query efficiency after refactoring or adding new features
Quick Start
- Step 1: Run prisma-query-optimizer on your codebase to generate a Prisma Query Analysis report
- Step 2: Review the Critical Issues, Warnings, and Suggestions in the report and identify high-priority fixes
- Step 3: Implement fixes (include relations, add indexes, paginate, and optimize counts) and re-run to verify improvements
Best Practices
- Use include to prevent N+1 queries by loading related data upfront instead of looping and querying per item
- Avoid lazy loading; include related data or select only what you need to minimize data transfer
- Add indexes in schema.prisma for foreign keys, fields used in where/orderBy, and unique lookups to speed filters
- Eliminate redundant queries by reusing cached or previously fetched results within the same request
- Paginate large findMany queries and prefer counting with count(...) when appropriate to avoid full fetches
Example Use Cases
- N+1 pattern: looping over users and fetching posts per user; fix by including posts in the initial query
- Missing eager loading: accessing user.posts after the initial user query; fix by including posts in findUnique
- Missing index: filtering by authorId in Post queries; fix by adding @@index([authorId]) to Post model
- Redundant queries: fetching the same user twice in one request; fix by reusing the first result
- Unpaginated findMany: retrieving all posts without take/skip; fix by adding pagination and ordering