index-advisor
Skill0 starsChanged 38 days agoMITView on GitHub
Recommends, orders, and prunes indexes for a specific query or table - composite column order, selectivity rules, partial and covering indexes, duplicate/unused cleanup, and write-amplification tradeoffs. Use when a query is slow and EXPLAIN shows a Seq Scan or a sort, before adding a CREATE INDEX, or when auditing a table's index set for bloat or duplicates. Do NOT use to diagnose an unknown slow query from scratch - start with sql-query-optimizer; do NOT use when the query shape itself is the problem (function-wrapped predicates, leading wildcards, correlated subqueries) - use query-rewriter instead; do NOT use when the table is too large and needs partitioning or a time-series strategy - use partition-planner instead.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- fatih-developer/fth-skillstheir own version, first seen Oct 13, 2026
- srikanth-manivannan/claude-agent-factorytheir own version, first seen Jun 26, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- fatih-developer/fth-skills★ 7same name
- srikanth-manivannan/claude-agent-factory★ 1same 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 repository7 other files it gives its agents.
- connection-pool-tunerSkill
- explain-plan-readerSkill
- migration-safety-checkerSkill
- n-plus-one-hunterSkill
- partition-plannerSkill
- query-rewriterSkill
- replication-lag-debuggerSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 8 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
Make it partial when one predicate is always present: If queries always filter the same constant, scope the index: CREATE INDEX ON orders …
- Distinctive: line 54
Every recommendation cites the plan line it fixes.
- Distinctive: line 55
Every recommended index carries a selectivity estimate showing the predicate lands under the ~10% usefulness line.
- Distinctive: line 57
Every drop names the evidence (idx_scan = 0, or the index it duplicates).
- Distinctive: line 62
Do NOT index tiny tables (under a few hundred rows) - a Seq Scan beats an index lookup.
- Distinctive: line 63
Do NOT index a predicate that matches more than ~10-20% of the table and expect the planner to use it.
- Very specific: line 64
Do NOT index a column only ever used inside a function or with a leading % wildcard unless you build the matching expression index - …
- Distinctive: line 65
Do NOT create a single-column index whose column is already the leftmost prefix of an existing composite.
- Distinctive: line 66
Do NOT add an index without re-running the plan to confirm it is used and faster.
- Distinctive: line 67
Do NOT solve a too-large table by indexing - that is partition-planner's job.
≈ “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
Index Advisor
An index trades write speed and disk for read speed. Add the fewest indexes that serve real query shapes, order their columns deliberately, and prove every change with a plan. The costly mistake is the speculative index: it fails to help the read (wrong column order, predicate too unselective) while permanently taxing every write. This skill owns index design only - plan diagnosis belongs to sql-query-optimizer, and query restructuring belongs to query-rewriter.
Inputs to collect
- The slow query text and its
EXPLAIN (ANALYZE, BUFFERS)output (Postgres) orEXPLAIN ANALYZE/EXPLAIN FORMAT=JSON(MySQL). No plan, no recommendation. - The table's row count and the existing index list (
\d table/SHOW INDEX). - Predicate selectivity: roughly what fraction of rows each WHERE predicate matches. Estimate from
n_distinctinpg_statsor a quickCOUNT(*)ratio; label estimates as guesses. - The write profile: is this table write-hot (high INSERT/UPDATE rate), and which columns get updated?
- For an audit:
pg_stat_user_indexes(or the MySQL equivalent) over a representative window.
Workflow
- Capture evidence first. Get the actual access path from the plan. Note the Seq Scan, expensive Sort, or rows-removed-by-filter that an index would eliminate. Never recommend an index without a plan that shows the problem.
- Check selectivity before designing anything. A B-tree index pays off when the predicate selects roughly under 5-10% of rows; once a query fetches more than ~10-20% of a table, the planner rightly prefers a Seq Scan and the index will sit unused. A column with very low cardinality (boolean, status, enum with a handful of values) is not worth a plain index - that is partial-index territory (step 4) or no index at all.
- Order composite columns: equality first, then one range/sort. Extract the query shape - equality predicates (
=,IN), the one range/sort column (<,>,BETWEEN,ORDER BY), and the returned columns. Equality columns lead, then a single range or sort column.(tenant_id, created_at)servesWHERE tenant_id = ? ORDER BY created_at; reversing it does not. By the leftmost-prefix rule,(a, b, c)already serves(a)and(a, b)- so do not also create(a); it is redundant for lookups. Among equality columns, order for prefix reuse across the workload's query shapes. - Make it partial when one predicate is always present. If queries always filter the same constant, scope the index:
CREATE INDEX ON orders (created_at) WHERE status = 'pending'is tiny and hot. Prefer a partial index over a plain index on a low-cardinality column. - Make it covering when the heap fetch dominates. To get an index-only scan: in Postgres add
INCLUDE (amount, status); in MySQL InnoDB the PK is already appended, so add the covered columns to the index key. Confirm with the plan showingIndex Only Scan(Postgres) orUsing index(MySQL). - Prune dead weight. Find unused indexes via
pg_stat_user_indexeswhereidx_scan = 0over a representative window (long enough to cover monthly jobs). Find duplicates by identical or prefix-redundant column lists and drop the subset. Apply withCREATE INDEX CONCURRENTLY/DROP INDEX CONCURRENTLY(Postgres) to avoid table locks. - Weigh the write cost before keeping it. Every secondary index adds roughly one extra write per row change - five indexes means an insert does ~6x the index maintenance of an unindexed table - and bloats the WAL/redo log. Updating an indexed column defeats HOT/in-place updates, turning cheap updates into full row versions. More than ~5 indexes on a write-hot table is a red flag demanding per-index justification; prefer one well-ordered composite over several single-column indexes.
- Verify. Re-run the plan and confirm the planner uses the new index AND the query is actually faster (compare actual times, not costs). If it does not, drop the index.
Worked example
Query: SELECT id, total FROM orders WHERE tenant_id = 42 AND status = 'pending' ORDER BY created_at DESC LIMIT 20 on 40M rows.
Bad: CREATE INDEX ON orders (created_at); - the plan still filters 40M rows' worth of other tenants after the index scan; tenant_id (the selective equality, ~0.1% of rows) is not in the index, and status alone matches 30% of rows so it cannot carry the query either.
Good:
CREATE INDEX CONCURRENTLY idx_orders_tenant_pending
ON orders (tenant_id, created_at DESC)
INCLUDE (total)
WHERE status = 'pending';Equality column leads, the sort column follows so the ORDER BY ... LIMIT 20 reads pre-sorted, the always-present status = 'pending' becomes a partial predicate keeping the index small, and INCLUDE (total) yields an Index Only Scan. Verified: plan goes from Seq Scan + Sort (4.8s) to Index Only Scan (2ms).
Deliverable
Produce an index change plan containing: each CREATE INDEX / DROP INDEX statement (CONCURRENTLY where supported), the plan line each addition fixes and the selectivity estimate justifying it, the evidence for each drop (idx_scan = 0 window or the index it duplicates), the net index count and write-cost delta for the table, and the before/after EXPLAIN ANALYZE comparison.
Quality bar
- Every recommendation cites the plan line it fixes; no speculative indexes.
- Every recommended index carries a selectivity estimate showing the predicate lands under the ~10% usefulness line.
- Column order is justified by the equality-then-range rule, not guessed.
- Every drop names the evidence (idx_scan = 0, or the index it duplicates).
- Net index count and write cost are stated, not just the additions.
Do NOT
- Do NOT index tiny tables (under a few hundred rows) - a Seq Scan beats an index lookup.
- Do NOT index a predicate that matches more than ~10-20% of the table and expect the planner to use it.
- Do NOT index a column only ever used inside a function or with a leading
%wildcard unless you build the matching expression index - otherwise the planner cannot use it. - Do NOT create a single-column index whose column is already the leftmost prefix of an existing composite.
- Do NOT add an index without re-running the plan to confirm it is used and faster.
- Do NOT solve a too-large table by indexing - that is partition-planner's job; do NOT rewrite the query shape - that is query-rewriter's job.
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.

