database-query-optimization
Skill6 starsChanged 6 months agoMITView on GitHub
When addressing slow application endpoints, high database CPU usage, or standardizing data access patterns.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Mushfiqur-Rahman-Robin/coding-rulestheir own version, first seen Oct 13, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- Mushfiqur-Rahman-Robin/coding-rules★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- caching-strategiesSkill
- event-driven-designSkill
- logging-observability-standardsSkill
- api-design-restSkill
- error-handling-architectureSkill
- code-review-guidelinesSkill
- ci-cd-pipeline-architectureSkill
- debugging-strategiesSkill
- git-workflow-branchingSkill
- dom-security-hardeningSkill
- react-component-designSkill
- state-management-patternsSkill
- accessibility-ui-designSkill
The file
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 11 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 51
Profile the Bottleneck: Run EXPLAIN ANALYZE on slow queries to identify sequential scans and high-cost operations
- Distinctive: line 56
Add Indexes: Add B-Tree indexes to WHERE, JOIN, and ORDER BY columns in slow queries
- Distinctive: line 61
MUST explicitly define selected columns (NEVER use SELECT * in production)
- Distinctive: line 62
MUST NEVER have database operations inside loops
- Distinctive: line 63
MUST perform filtering and aggregation in the database, not application memory
- Distinctive: line 64
MUST enforce LIMIT and OFFSET on collection queries
- Distinctive: line 65
MUST EXPLAIN before adding indexes (verify they reduce cost)
- Distinctive: line 66
MUST rollback indexes if they degrade INSERT/UPDATE performance
- Distinctive: line 67
MUST NOT over-index (each index has maintenance cost)
- Distinctive: line 79
No query metrics/logs available
- Distinctive: line 104
All user input MUST be parameterized (prevent SQL injection)
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Database Query Optimization
Purpose
Slow databases kill applications. This skill replaces guesswork with systematic performance analysis, using EXPLAIN plans and profiling to eliminate N+1 queries, eliminate unnecessary scans, and add targeted indexes so the database bears the computational load, not the application.
When to use
- Writing complex SQL queries or ORM access functions
- Resolving performance bottlenecks on read-heavy endpoints
- Designing schema migrations for growing datasets
- Refactoring loops that make repeated database calls
When NOT to use
- Schema design (different concern)
- Database selection (architectural decision)
- Caching strategies (use Caching Strategies skill)
- Application-level performance (profilers, algorithms)
Inputs required
- Slow query logs or endpoint metrics
- ORM code accessing the database
- Database schema (tables, columns, indexes)
- EXPLAIN ANALYZE capability (test environment)
Workflow
- Profile the Bottleneck: Run EXPLAIN ANALYZE on slow queries to identify sequential scans and high-cost operations
- Identify N+1: Locate loops making repetitive database calls for the same entity type
- Measure Selectivity: Analyze WHERE clause filters and add indexes to highly selective columns
- Replace Loops: Replace N+1 with single IN queries or ORM eager-loading (JOINs)
- Remove Over-Fetching: Replace SELECT * with explicit column names
- Add Indexes: Add B-Tree indexes to WHERE, JOIN, and ORDER BY columns in slow queries
- Paginate: Enforce LIMIT and OFFSET (or cursor pagination) on all collection queries
- Verify Performance: Re-run EXPLAIN ANALYZE and benchmark end-to-end latency
Rules
- MUST explicitly define selected columns (NEVER use SELECT * in production)
- MUST NEVER have database operations inside loops
- MUST perform filtering and aggregation in the database, not application memory
- MUST enforce LIMIT and OFFSET on collection queries
- MUST EXPLAIN before adding indexes (verify they reduce cost)
- MUST rollback indexes if they degrade INSERT/UPDATE performance
- MUST NOT over-index (each index has maintenance cost)
Anti-patterns
- The N+1 Problem: Fetching 50 users, then making 50 individual queries to fetch each user's profile
- Over-Indexing: Adding an index to every single column (degrades INSERT/UPDATE performance)
- Application-Side Filtering: Fetching 10,000 rows from DB and using
filter()in JavaScript - SELECT * in Production: Fetching all columns including BLOBs when needing only
idandname - Unbounded Queries: Collection endpoints without LIMIT/OFFSET returning millions of rows
- Ignoring Selectivity: Adding indexes to low-cardinality columns (gender, status)
Failure conditions
- Database unavailable for profiling
- No query metrics/logs available
- EXPLAIN ANALYZE not supported by database
- Migration lacks rollback strategy
- Index changes cause lock timeouts on large tables
Validation checklist
- EXPLAIN ANALYZE shows acceptable query cost (< 1000 for simple queries)
- No sequential scans on large tables (use indexes)
- SELECT explicitly lists columns (no SELECT *)
- No loops making repeated database calls
- N+1 problems replaced with JOIN or ORM eager-load
- WHERE/JOIN/ORDER BY columns are indexed
- Collection queries enforce LIMIT and OFFSET
- No unused indexes (maintenance burden)
- Low-cardinality columns (gender, status) are NOT indexed
- Benchmark shows latency improvement (confirm end-to-end)
Output format
- SQL format: ANSI standard, explicitly selecting columns, using parameterized queries
- ORM calls: Using eager-load or relationship methods (not loops)
- Schema changes: Migration files with forward and rollback steps
- Indexes: B-Tree on high-selectivity columns, documented in schema
- Validation: EXPLAIN ANALYZE output showing acceptable costs
Security considerations
- All user input MUST be parameterized (prevent SQL injection)
- Query results MUST be accessible by user (respect permissions)
- Large result sets MUST be paginated (prevent DOS)
- Timing attacks: ensure query timing doesn't leak existence of data
Agent execution notes
- Agent MAY: Add indexes, create ORM relationships, replace loops with joins, add LIMIT/OFFSET
- Agent MUST NEVER: Use SELECT *, create loops with queries, add untested indexes, bypass pagination
- Agent MUST ASK: Before dropping existing indexes, before major query rewrites, before schema changes
- Agent MUST VALIDATE: EXPLAIN ANALYZE shows improvement, no N+1 remaining, pagination enforced
Example
*❌ Anti-pattern (N+1, SELECT , no pagination, missing indexes):
// N+1 problem: 1 query for users + 50 queries for posts
const users = await User.findAll(); // SELECT * (over-fetching)
for (const user of users) {
const posts = await Post.find({ userId: user.id }); // 50 individual queries
console.log(user, posts);
}
// Application-side filtering
const allUsers = await User.find({});
const filtered = allUsers.filter(u => u.status === 'active');✅ Correct pattern (Join, eager-load, explicit columns, paginated):
// Single optimized query with JOIN and explicit columns
const usersWithPosts = await User.findAll({
attributes: ['id', 'username', 'email'],
include: [{
model: Post,
attributes: ['id', 'title', 'createdAt'],
required: true
}],
limit: 20,
offset: 0,
order: [['createdAt', 'DESC']]
});
// Or raw SQL with pagination
const query = `
SELECT u.id, u.username, p.id, p.title
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
WHERE u.status = $1
ORDER BY u.created_at DESC
LIMIT $2 OFFSET $3
`;
const result = await db.query(query, ['active', 20, 0]);
// Indexes created
// CREATE INDEX idx_posts_user_id ON posts(user_id);
// CREATE INDEX idx_users_status ON users(status) WHERE status = 'active';Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

