mcpField
D
db-indexing

db-indexing

github.com/hainrixzData & databases2172 installsUpdated 4d ago
Repository

About db-indexing

db-indexing is a skill for checking whether database indexes match query patterns, aimed at database design and performance reviews. It examines foreign-key coverage, composite ordering, and specialized index types, while distinguishing static signals from runtime verification.

Key features

  1. 01Check indexes on foreign-key columns
  2. 02Check ESR order in composite indexes
  3. 03Identify covering and partial index opportunities
  4. 04Check JSON, full-text, and geospatial index types
  5. 05Verify missing foreign-key indexes with queries

Use cases

  1. 01Review index definitions in migrations
  2. 02Find foreign-key columns without indexes
  3. 03Check whether predicates need specialized indexes

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/hainrixz/claude-db --skill db-indexing

After installing, type/db-indexingin Claude Code to confirm it loaded.

Details

From the project README

db-indexing (M11)

Indexing is the single heaviest Performance & Scale (axis performance) lever (relational weight 20, Indexación). This module checks whether the indexes that exist match how the data is queried — missing, mis-ordered, or wrong-type indexes turn a sub-millisecond lookup into a sequential scan.

What it checks

  1. Composite order (ESR) — multi-column indexes should order columns Equality → Sort → Range. A leading range/low-selectivity column wastes the index.
  2. Covering / partial — frequent SELECT a,b WHERE c benefits from an INCLUDE covering index; queries always filtered on a predicate (WHERE deleted_at IS NULL) benefit from a partial index.
  3. Specialized types — GIN for jsonb/array/FTS containment, GiST/SP-GiST for geometry/range, BRIN for naturally-ordered append-only columns (timestamps). Flag full-text/geo/JSONB filters served by a plain B-tree (or no index).
  4. FK-no-index — every foreign key column should have a covering index; an unindexed FK forces a sequential scan on the referenced side during ON DELETE/ON UPDATE and on joins. This is the highest-yield, lowest-risk index finding.

Score / axis

Feeds performance only (relational Indexación w20; Indexación category in every NoSQL profile).

Tier-0 (static)

Parse DDL/migrations for declared indexes and FKs; cross-reference visible query patterns (ORM where/orderBy, raw SQL) against index columns. Detect FK columns with no matching index prefix, composite indexes with a non-equality leading column, and JSONB/array/FTS/geo predicates with no specialized index. Whether an index is actually used is runtime truth → needs_api at Tier-0.

Tier-1 (verification query) — FK-no-index (Postgres)

SELECT conrelid::regclass AS tbl, conname,
       pg_get_constraintdef(c.oid) AS fk
FROM pg_constraint c
WHERE c.contype = 'f'
  AND NOT EXISTS (
    SELECT 1 FROM pg_index i
    WHERE i.indrelid = c.conrelid
      AND (c.conkey[1]) = i.indkey[0]   -- leading index column == first FK column
  );

Method index_check. Each returned row is a confirmed unindexed FK (established). For ESR/covering, EXPLAIN (ANALYZE, BUFFERS) on the real query (method explain_plan, Tier-2) confirms the scan type.

Findings

Emit findings per schema/finding.schema.json. Examples:

  • M11.orders.customer_id_fk_unindexed — FK column with no covering index (severity:3, warn, axis performance, confidence directional static / established Tier-1, fixable: auto — CREATE INDEX CONCURRENTLY).
  • M11.events.composite_order_esr — leading range column in a composite index (severity:2, warn, directional, fixable: proposed).
  • M11.posts.jsonb_no_gin — jsonb containment filter with no GIN index (severity:3, warn, directional, fixable: proposed).

Each finding: evidence.observed quotes the FK/index DDL or query verbatim; verification.reproduce is the catalog query above (FK-no-index) or an EXPLAIN referencing $DATABASE_URL; expected_impact is banded + confidence-tagged (no naked %).

Honesty

  • A missing index is not always a defect — a tiny lookup table or a write-heavy table can be slower with an index. Scope severity to table size/access frequency; default directional without stats.
  • Never quote a latency/row-count improvement number; magnitude is high|medium|low only.
  • CREATE INDEX CONCURRENTLY is auto-fixable for FK gaps (additive, non-blocking, verifiable); composite reorders and partial indexes are proposed because intent may differ.

Comments

Markdown supported