본문으로 건너뛰기
cccskills
무료GitHub에 공개

db-query-plan-analyzer

Reads `EXPLAIN` / `EXPLAIN ANALYZE` output from PostgreSQL, MySQL, or SQLite - identifies the dominant cost (sequential scan, nested loop, sort spill, missing index, type-cast preventing index use), proposes the specific index or query rewrite to fix it, and emits the candidate `CREATE INDEX` statement. Use when load testing or production telemetry shows the database as the bottleneck and the team needs targeted query-level remediation.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa스타 13(GitHub 13 + cccskills 0)
연동 도구PostgreSQLMySQL

실행 점수 미검증

설치 방법 보기

포함된 파일(3)

  • SKILL.md7.0 KB
  • .tessl-plugin/plugin.json578 B
  • references/plan-signatures.md4.8 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

db-query-plan-analyzer

Overview

Most API perf regressions resolve to one of:

  1. A new query running unindexed (sequential scan over a growing table).
  2. A query joining on the wrong column type (implicit cast prevents index use).
  3. A sort that doesn't fit in work_mem and spills to disk.
  4. A query plan that started using a nested loop where a hash join would be faster (or vice versa) due to stale stats.
  5. A query touching N+1 rows because of an ORM N+1 access pattern.

EXPLAIN ANALYZE (PostgreSQL), EXPLAIN ANALYZE (MySQL 8.0+), or EXPLAIN QUERY PLAN (SQLite) reveals which case you're in. This skill reads that output and proposes the fix. The query-plan vocabulary (Sequential Scan, Index Scan, Nested Loop) comes from PostgreSQL's Using EXPLAIN.

When to use

  • A load test showed DB-bound latency growth.
  • An APM tool (Datadog / New Relic / Grafana) flagged a slow query.
  • A production incident traced to a specific query.
  • An EXPLAIN ANALYZE was captured but the team can't tell which cost is dominant.

If the bottleneck is connection-pool exhaustion or replication lag, this skill doesn't apply - those are infrastructure concerns.

Step 1 - Get a real EXPLAIN ANALYZE

Always use ANALYZE (it runs the query and reports actual rows + time); plain EXPLAIN gives only planner estimates, which can be wildly wrong.

PostgreSQL

EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON, SETTINGS)
SELECT o.id, o.status
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE c.email = 'test@example.com'
  AND o.created_at >= NOW() - INTERVAL '30 days'
ORDER BY o.created_at DESC
LIMIT 50;

BUFFERS adds I/O statistics; FORMAT JSON produces machine- readable output; SETTINGS shows session-specific settings that affected the plan (pg-explain).

MySQL 8.0+

EXPLAIN ANALYZE SELECT ...;

Output is a tree representation similar to PostgreSQL.

SQLite

EXPLAIN QUERY PLAN SELECT ...;

SQLite's output is simpler - no costs, just the access strategy (Index / Sequential / Search).

Step 2 - Identify the dominant cost

Read the plan from the innermost nodes outward (the deepest nesting is what runs first). The dominant cost is the node with the highest actual time in PostgreSQL or the highest cumulative cost in MySQL. Match the node to its meaning using the cost-signature table in references/plan-signatures.md.

Step 3 - Match cost to fix

Look up the diagnosis in the diagnosis-to-fix table in references/plan-signatures.md (Seq Scan -> add index, type cast -> fix app code, sort spill -> pre-sorted index or larger work_mem, N+1 -> eager-load at the ORM, etc.).

Step 4 - Emit the candidate index / rewrite

Per pg-explain index-creation conventions:

-- Single-column index on a high-selectivity column
CREATE INDEX idx_orders_customer_id ON orders(customer_id);

-- Composite index - order matters; leading column is the most selective
CREATE INDEX idx_orders_customer_created ON orders(customer_id, created_at DESC);

-- Partial index - covers only the rows the query touches
CREATE INDEX idx_orders_active ON orders(created_at DESC) WHERE status = 'active';

-- Functional index - for predicates with a function on the column
CREATE INDEX idx_users_email_lower ON users(LOWER(email));

-- Covering index (PostgreSQL 11+) - avoids a heap fetch
CREATE INDEX idx_orders_summary ON orders(customer_id) INCLUDE (status, total);

For which column leads, when to use partial vs. functional indexes, and low-cardinality pitfalls, see the index-choice principles in references/plan-signatures.md.

Output format

## Slow query analysis - `<query-id-or-snippet>`

**Database:** postgresql 17 | mysql 8.0 | sqlite
**Query:** (excerpt)

```sql
SELECT o.id, o.status FROM orders o JOIN customers c ON c.id = o.customer_id
WHERE c.email = 'test@example.com' AND o.created_at >= NOW() - INTERVAL '30 days'
ORDER BY o.created_at DESC LIMIT 50;
```

### Plan summary

| Node                         | Actual time | Rows  | Cost driver |
|------------------------------|------------:|------:|-------------|
| Seq Scan on orders (filter)   |       2.3s | 1.2M  | **DOMINANT** - no index on (customer_id, created_at) |
| Index Scan on customers (email) |     1ms |    1   | (covered)    |

### Diagnosis

The query joins `orders` to `customers` on `customer_id`, but
`orders` has no index on `customer_id` - the planner falls back to a
sequential scan over 1.2M rows, then post-filters by date.

### Recommended fix

```sql
CREATE INDEX idx_orders_customer_created ON orders(customer_id, created_at DESC);
```

Composite index ordered by `customer_id` first (the join predicate),
then `created_at` descending - satisfies both the filter and the
ORDER BY without a separate sort.

### Expected impact

- Plan changes from Seq Scan to Index Scan.
- Actual time drops from ~2.3s to ~50ms (rows-touched falls from
  1.2M to ~50).
- `Buffers: shared read` drops correspondingly; less I/O on the
  database.

### Validation

After applying:

```sql
EXPLAIN (ANALYZE, BUFFERS) SELECT ...;
```

Confirm the new plan uses `idx_orders_customer_created` and the
actual time is below the budget.

Anti-patterns

See the anti-patterns table in references/plan-signatures.md (speculative indexing, reading EXPLAIN without ANALYZE, optimizing a non-dominant node, skipping ANALYZE after a bulk load).

Limitations

  • Vendor-specific output. PostgreSQL's EXPLAIN is the most detailed; MySQL 8.0+ caught up; SQLite is sparse. The skill is most useful for postgres-flavored databases.
  • Distributed databases. Spanner, CockroachDB, Citus produce different plans - the skill's heuristics translate but the specific node names differ.
  • Doesn't replace a DBA. For complex multi-CTE queries with recursive sub-plans, a human DBA is faster than this skill's pattern matching.

References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

testland의 스킬 모두 보기

이 스킬의 문제 신고