agentleFS
sf-scalarsf-scalar/skiLL.Md/skills/backend/database-query-optimization/SKILL.md

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

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
  1. Distinctive:

    Profile the Bottleneck: Run EXPLAIN ANALYZE on slow queries to identify sequential scans and high-cost operations

    line 51
  2. Distinctive:

    Add Indexes: Add B-Tree indexes to WHERE, JOIN, and ORDER BY columns in slow queries

    line 56
  3. Distinctive:

    MUST explicitly define selected columns (NEVER use SELECT * in production)

    line 61
  4. Distinctive:

    MUST NEVER have database operations inside loops

    line 62
  5. Distinctive:

    MUST perform filtering and aggregation in the database, not application memory

    line 63
  6. Distinctive:

    MUST enforce LIMIT and OFFSET on collection queries

    line 64
  7. Distinctive:

    MUST EXPLAIN before adding indexes (verify they reduce cost)

    line 65
  8. Distinctive:

    MUST rollback indexes if they degrade INSERT/UPDATE performance

    line 66
  9. Distinctive:

    MUST NOT over-index (each index has maintenance cost)

    line 67
  10. Distinctive:

    No query metrics/logs available

    line 79
  11. Distinctive:

    All user input MUST be parameterized (prevent SQL injection)

    line 104

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

  1. Profile the Bottleneck: Run EXPLAIN ANALYZE on slow queries to identify sequential scans and high-cost operations
  2. Identify N+1: Locate loops making repetitive database calls for the same entity type
  3. Measure Selectivity: Analyze WHERE clause filters and add indexes to highly selective columns
  4. Replace Loops: Replace N+1 with single IN queries or ORM eager-loading (JOINs)
  5. Remove Over-Fetching: Replace SELECT * with explicit column names
  6. Add Indexes: Add B-Tree indexes to WHERE, JOIN, and ORDER BY columns in slow queries
  7. Paginate: Enforce LIMIT and OFFSET (or cursor pagination) on all collection queries
  8. 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 id and name
  • 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';

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.