Install
$ agentstack add skill-celticht32-couchbase-skills-for-claude-ai-couchbase-sqlpp-tuning ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Couchbase SQL++ tuning
A skill for diagnosing and fixing slow SQL++ / N1QL queries on Couchbase Server (7.x and 8.x). The mechanics of reading execution plans, choosing the right index type, fixing common anti-patterns, and wiring up the diagnostic tools.
Distinct from the sibling skills:
couchbase-data-modeling— how to MODEL the data (document shape, boundaries, access patterns)couchbase-sizing— how to size the clustercouchbase-app-integration— how to write app code that uses Couchbasecouchbase-migration-execution— how to move data INTO Couchbasecouchbase-mcp— operating the cluster (the MCP server'scb_explain_query,cb_index_advisor,cb_perf_*tools)couchbase-sqlpp-tuning(this skill) — making queries that already exist run faster
If the conversation is "this query is slow, what do I do," this is the right skill.
When this skill applies
- "Why is this query slow?"
- "How do I read this EXPLAIN plan?"
- "Why isn't my index being used?"
- "I'm seeing PrimaryScan / IntersectScan — is that bad?"
- "How do I make this a covering index?"
- "Should I use a partial index here?"
- "How do I index an array field with ANY / EVERY / UNNEST?"
- "ADVISE recommended this index — should I create it?"
- "How do I tune pagination — LIMIT / OFFSET is slow at high offsets"
- "What does kernTime / servTime / execTime mean in the profile?"
- "Can I force the optimizer to use a specific index?"
- "What do the cost-based optimizer hints do in 7.6+?"
Core principles (read first)
These are the headline rules. Read them before diving into references.
- Pareto applies to query tuning. 80% of perf problems come from 20% of queries. Use
system:completed_requests(or the MCPcb_perf_longest_running/cb_perf_most_frequenttools) to find that 20% first. Don't tune the wrong queries.
- CBO needs stats to help; without them it falls back to rule-based logic. Couchbase has a cost-based optimizer (GA in 7.0, EE only), but it needs statistics on indexes and collections to do its job. Without stats, single-keyspace access is rule-based — index cardinality doesn't influence the choice, the optimizer picks based on which leading keys are in the WHERE clause. In 7.6+, statistics are gathered automatically when an index is created or built; in earlier versions, you run
UPDATE STATISTICSmanually. Either way: design indexes so the rules pick them, and runUPDATE STATISTICSon a schedule.
- The leading key of the index must appear in the WHERE clause for an index to be picked. If a field can be missing, you need
INCLUDE MISSINGon the leading key, or you needIS NOT MISSING/IS NOT NULLin the WHERE clause to force selection.
- Cover the query when it's hot. A covering index includes every field the query SELECTs and filters on, so the query never touches the Data service. Look for
"covers": [...]in the EXPLAIN plan and the absence of aFetchoperator — that's the signal.
- Don't index low-cardinality fields like
docTypealone. It causes IntersectScans and wrong plans. Use a partial index (WHERE type = 'X') instead — the field gates the index, but isn't the leading key.
- Match the query shape to the index shape for arrays.
ANY ... SATISFIESandANY AND EVERYcan use array indexes; bareEVERYcannot.UNNESTmust use the exact same binding variable name as theCREATE INDEX ... FOR IN ....
- Avoid PrimaryScan in production. A PrimaryScan is the equivalent of a full table scan. Drop primary indexes in prod, or at least confirm no production query relies on one.
Pick the right reference
| Question | Read | |---|---| | "How do I read this EXPLAIN plan? What's PrimaryScan / IntersectScan / Fetch?" | references/explain-plan.md | | "What kind of index should I create? Covering / partial / array / composite / vector?" | references/index-design.md | | "Why isn't my index being used? Common query anti-patterns and how to fix them" | references/query-patterns.md | | "What does the cost-based optimizer do? What are the hints?" | references/cost-based-optimizer.md | | "How do I wire this up with the MCP server tools (cb_explain_query, cb_index_advisor, cb_perf_*)" | references/diagnostic-workflow.md | | "How do I do efficient pagination on a large result set?" | references/pagination.md | | "How do I tune queries that join across keyspaces?" | references/joins-and-cbo.md |
Workflow
The general approach to tuning a slow query:
1. Identify → Find the slow query (Pareto: top-20% by frequency × duration)
Tools: cb_perf_longest_running, cb_perf_most_frequent,
system:completed_requests
2. Understand → Run EXPLAIN. Read the plan.
Tools: cb_explain_query (returns plan + parsed findings)
What to look for: PrimaryScan? IntersectScan? Fetch present?
Is the leading key of an index in WHERE?
3. Hypothesize → Pick one of:
- Add a covering index (everything in the index, no Fetch)
- Add a partial index (smaller, indexed on a subset)
- Add an array index (DISTINCT ARRAY ... FOR ... IN ... END)
- Reshape the query (drop OR predicates, add IS NOT MISSING)
- Add a USE INDEX hint
Tools: cb_index_advisor (ADVISE) for index recommendations
4. Verify → Re-run EXPLAIN. Check the new index is picked.
Run the query. Check kernTime / servTime / execTime in the profile.
Tools: cb_explain_query, cb_query with profile=on
5. Iterate → Repeat until the query meets SLA, or further tuning has
diminishing returns. Most queries reach acceptable performance
in 1-3 iterations.
Anti-pattern checklist
Quick scan list — if you see any of these, jump to references/query-patterns.md:
SELECT *from a large keyspace (forces Fetch, can't cover)WHERE docType = 'X'as the leading filter (low-cardinality leading key)WHERE NOT (...),!=,NOT INpredicates (often not sargable)ORacross different fields (often forces IntersectScan)EVERY x IN arr SATISFIES ... ENDwithoutANY AND EVERY(no array index)UNNESTbinding variable not matching the index definitionLIMIT 10 OFFSET 1000000(deep pagination — use KeySet pagination)- Raw user input concatenated into the statement (injection + can't prepare)
- A query that runs thousands of times per second with no
PREPARE
Tooling
The MCP server in this project (celticht32/MCP-Couchbase) exposes the tuning tools you need:
| Tool | Purpose | |---|---| | cb_explain_query | EXPLAIN + parsed plan findings | | cb_index_advisor | ADVISE statement; recommends indexes | | cb_perf_longest_running | Top N queries by duration | | cb_perf_most_frequent | Top N queries by frequency | | cb_perf_largest_responses | Queries returning the most bytes | | cb_perf_large_result_count | Queries returning the most rows | | cb_perf_using_primary_index | Queries hitting the primary index (BAD in prod) | | cb_perf_not_using_covering_index | Queries that could be covered but aren't | | cb_perf_not_selective | Queries where the WHERE filter doesn't narrow much | | cb_perf_by_user | (8.x) attribute slow queries to a specific user | | cb_get_schema_for_collection | Sample document schema (for designing the right index) |
See references/diagnostic-workflow.md for the full step-by-step using these tools.
Version notes
- Pre-7.0: No scope/collection — indexes are bucket-level
- 7.0: Scopes and collections; covering, partial, array indexes; CBO went GA (preview was in 6.5) — requires
UPDATE STATISTICSto be useful - 7.1+:
INCLUDE MISSINGfor leading index keys (so docs without the leading-key field still get indexed) - 7.6+: CBO auto-gathers stats on index create/build; join-enumeration improvements;
/*+ ... */optimizer hints (productivity,ORDERED,USE HASH);UPDATE STATISTICSstill available for manual refresh - 8.0+: Vector indexes (HYPERSCALE / COMPOSITE VECTOR INDEX); Auto Update Statistics (AUS) keeps stats fresh automatically; FTS synonym sets; user lock/unlock; XDCR conflict logging
Always verify against the cluster version before recommending a feature — the MCP cb_mcp_status tool reports the version it has detected.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: celticht32
- Source: celticht32/Couchbase-Skills-for-Claude.ai
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.