Help us improve
Share bugs, ideas, or general feedback.
From yba-api
Analyzes PostgreSQL (and YugabyteDB) EXPLAIN / EXPLAIN ANALYZE query plans to identify performance issues, seq scans, and recommend indexes.
npx claudepluginhub yugabyte/yugabytedb-skills --plugin yb-rag-langchainHow this skill is triggered — by the user, by Claude, or both
Slash command
/yba-api:explain_plan_analyzerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
When a user provides a PostgreSQL or YugabyteDB EXPLAIN or EXPLAIN ANALYZE plan, work through these stages in order: parse → identify issues → recommend fixes → present clearly.
Applies C++ Core Guidelines to write, review, or refactor C++ code. Enforces modern, safe, and idiomatic practices for C++17/20/23.
Share bugs, ideas, or general feedback.
When a user provides a PostgreSQL or YugabyteDB EXPLAIN or EXPLAIN ANALYZE plan, work through these stages in order: parse → identify issues → recommend fixes → present clearly.
First determine what you're working with:
Note this at the start of your response, as it affects how confident you can be about findings.
For each node in the plan tree, extract where present:
Seq Scans are the first and most critical thing to evaluate.
Flag a Seq Scan as significant (🔴 Critical) if ANY of these apply:
| Condition | Reason |
|---|---|
| Estimated rows > 10,000 | Large table being fully scanned |
| Actual rows > 10,000 (if ANALYZE) | Confirmed large scan |
| Node is inside a Nested Loop with loops > 10 | Cost multiplies: even 500-row scans become expensive |
| "Rows removed by filter" > 50,000 | Massive discard ratio — filter could become an index |
| Seq Scan cost > 30% of total plan cost | Dominates the query |
Flag a Seq Scan as minor (🟡 Low priority) if:
For YugabyteDB: Lower the threshold to 1,000 rows for 🔴 Critical. LSM-tree storage makes sequential scans significantly more expensive than in standard Postgres due to SST file structure. Mention this explicitly.
Index recommendation format:
-- If filter is: (status = 'pending')
CREATE INDEX ON orders (status);
-- If filter is: (user_id = $1 AND created_at > $2)
CREATE INDEX ON orders (user_id, created_at);
-- If most rows have status='completed' and you only query 'pending':
CREATE INDEX ON orders (status) WHERE status != 'completed';
After seq scans, check for these in order of typical impact:
ANALYZE table_name; or CREATE STATISTICS for correlated columnsSET enable_nestloop = off temporarily to test, or add an index on the join columnBatches: N where N > 1 in a Hash nodework_memSET work_mem = '64MB'; (or higher, test in session first)Sort Method: external merge or external sortwork_memRows Removed by Index Recheck: N being high means lossy bitmap pageswork_mem so the bitmap stays exactStructure your response exactly as follows:
State whether this is EXPLAIN, EXPLAIN ANALYZE, or EXPLAIN (ANALYZE, BUFFERS), and note any limitations this places on the analysis.
1–2 sentences: what the query does, overall shape (joins, aggregations, etc.), and total cost or execution time if available.
One section per issue. For each:
orders — 450,000 rows")If no critical issues: say "No critical issues found."
Brief bullets for lower-priority findings (row estimate mismatches, memory spills, etc.)
If none: omit this section.
Numbered list, ordered by expected impact:
Keep this list actionable — real SQL commands where possible.