本文へ移動
cccskills
無料GitHub で公開

neo4j-query-tuning-skill

Diagnoses and fixes slow Neo4j Cypher queries by reading execution plans, identifying bad operators (AllNodesScan, CartesianProduct, Eager, NodeByLabelScan), and prescribing fixes (indexes, hints, query rewrites, runtime selection). Use when a query is slow, when EXPLAIN or PROFILE output needs interpretation, when dbHits or pageCacheHitRatio are poor, when cardinality estimation diverges from actuals, or when deciding between slotted/pipelined/parallel runtimes. Covers USING INDEX / USING SCAN / USING JOIN hints, db.stats.retrieve, SHOW QUERIES, SHOW TRANSACTIONS, TERMINATE TRANSACTION. Does NOT write new Cypher from scratch — use neo4j-cypher-skill. Does NOT cover GDS algorithm tuning — use neo4j-gds-skill. Does NOT cover index/constraint creation syntax details — use neo4j-cypher-skill references/indexes.md.

インストール方法を見る

含まれるファイル(4)

  • SKILL.md10.2 KB
  • README.md1.4 KB
  • references/plan-operators.md7.4 KB
  • references/stats-and-monitoring.md5.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

When to Use

  • Query takes unexpectedly long; need root-cause analysis
  • EXPLAIN/PROFILE output in hand — needs interpretation
  • Identifying which index is missing or unused
  • Deciding between slotted / pipelined / parallel runtimes
  • Monitoring live queries: SHOW QUERIES, SHOW TRANSACTIONS
  • Cardinality estimates wrong (plan replanning needed)

When NOT to Use

  • Writing Cypher from scratch → neo4j-cypher-skill
  • GDS algorithm performance → neo4j-gds-skill
  • Schema design / data modelling → neo4j-modeling-skill

EXPLAIN vs PROFILE

EXPLAINPROFILE
Executes query?NoYes
Returns data?NoYes
Shows rows (actual)NoYes
Shows dbHits (actual)NoYes
Shows estimatedRowsYesYes
CostZeroFull query cost

Run PROFILE twice — first run warms page cache; second gives representative metrics.

EXPLAIN MATCH (p:Person {email: $email}) RETURN p.name
PROFILE MATCH (p:Person {email: $email}) RETURN p.name

Query API alternative (no driver):

curl -X POST https://<host>/db/<db>/query/v2 \
  -u <user>:<pass> -H "Content-Type: application/json" \
  -d '{"statement": "EXPLAIN MATCH (p:Person {email: $email}) RETURN p.name", "parameters": {"email": "a@b.com"}}'

Key Plan Metrics

MetricGoodInvestigate if
dbHitsLow; drops after index addedHigh relative to rows
rowsShrinks early in planLarge until final operator
estimatedRowsClose to rows>10× divergence from actual
pageCacheHitRatio>0.99<0.90 (disk I/O bottleneck)
pageCacheHitsHigh—
pageCacheMissesNear 0Rising (page cache too small)

Read plans bottom-up — leaf operators at bottom initiate data retrieval.


Operator Reference

OperatorGood/BadMeaningFix
NodeIndexSeek✓Exact match via RANGE/LOOKUP index—
NodeUniqueIndexSeek✓Unique constraint index hit—
NodeIndexContainsScan✓TEXT index CONTAINS / STARTS WITH—
NodeIndexScan~Full index scan (no predicate)Add WHERE predicate or composite index
NodeByLabelScan✗Scans all nodes of labelAdd RANGE index on lookup property
AllNodesScan✗✗Scans entire node storeAdd label + index to MATCH
Expand(All)~Traverse relationships from nodeNormal; limit with LIMIT or WHERE
Expand(Into)~Find rels between two matched nodesNormal for known-endpoint joins
Filter~Predicate applied after scanMove predicate into WHERE with index
CartesianProduct✗No join predicate between two MATCHAdd WHERE join or use WITH between MATCHes
NodeHashJoin~Hash join on node IDsNormal; planner chose hash join
ValueHashJoin~Hash join on valuesNormal; watch memory for large inputs
EagerAggregation~Full aggregation (ORDER BY, count(*))Normal for aggregates
Aggregation✓Streaming aggregation—
Eager✗Read/write conflict; materialises all rowsSee Eager fix strategies below
Sort~Full sort — O(n log n)Add LIMIT before Sort; push LIMIT earlier
Top✓Sort+Limit combined — O(n log k)Preferred over Sort+Limit
Limit✓Truncates rows earlyPush as early as possible
Skip~Offset paginationUse keyset pagination on large graphs
ProduceResults—Final output operatorRoot of tree
UndirectedRelationshipByIdSeekPipe~Lookup by relationship IDAvoid id(r) — use elementId(r)

Full operator reference → references/plan-operators.md


Diagnostic Workflow (Agent Runbook)

Step 1 — Baseline Plan

EXPLAIN <query>

Scan output for AllNodesScan, NodeByLabelScan, CartesianProduct, Eager.

Step 2 — Check Indexes

SHOW INDEXES YIELD name, type, labelsOrTypes, properties, state
WHERE state = 'ONLINE'

Find whether the label/property from the bad operator has an index.

Step 3 — Create Missing Index

// RANGE index for equality/range predicates:
CREATE INDEX person_email IF NOT EXISTS FOR (n:Person) ON (n.email)
// TEXT index for CONTAINS/ENDS WITH:
CREATE TEXT INDEX person_bio IF NOT EXISTS FOR (n:Person) ON (n.bio)
// Composite for multi-property lookup:
CREATE INDEX order_status_date IF NOT EXISTS FOR (n:Order) ON (n.status, n.createdAt)

Wait for state = 'ONLINE' before measuring.

Step 4 — Profile After Fix

PROFILE <query>

Compare dbHits and elapsed ms before/after. Target: NodeIndexSeek replaces scan operators.

Step 5 — Stale Statistics (if estimatedRows wildly off)

CALL db.prepareForReplanning()
// or resample a specific index:
CALL db.resampleIndex("person_email")
// or resample all outdated:
CALL db.resampleOutdatedIndexes()

Config: dbms.cypher.statistics_divergence_threshold (default 0.75 — plan expires when stat changes >75%).


Fixing Common Plan Problems

Missing Index → NodeByLabelScan / AllNodesScan

// Force index hint when planner ignores it:
MATCH (p:Person {email: $email})
USING INDEX p:Person(email)
RETURN p.name
// Force label scan (sometimes faster for high selectivity):
MATCH (p:Person {email: $email})
USING SCAN p:Person
RETURN p.name

Wrong Anchor — Planner Picks Wrong Starting Node

Reorder MATCH or use hints:

// Force join at specific node:
MATCH (a:Author)-[:WROTE]->(b:Book)-[:IN_CATEGORY]->(c:Category {name: $cat})
USING JOIN ON b
RETURN a.name, b.title

CartesianProduct — Two Unconnected MATCHes

// Bad (Cartesian product):
MATCH (a:Author {id: $aid})
MATCH (b:Book  {id: $bid})
RETURN a.name, b.title

// Good (explicit join or WITH):
MATCH (a:Author {id: $aid})-[:WROTE]->(b:Book {id: $bid})
RETURN a.name, b.title
// Or: WITH between them to reset planning context

Eager — Read/Write Conflict

Three strategies (pick simplest):

  1. Add specific labels to MATCH nodes so planner distinguishes read/write sets
  2. Collect-then-write: WITH collect(n) AS nodes UNWIND nodes AS n SET n.x = 1
  3. CALL IN TRANSACTIONS: isolates each batch in its own transaction
CYPHER 25
MATCH (p:Person) WHERE p.score > 100
CALL (p) { SET p.tier = 'gold' } IN TRANSACTIONS OF 1000 ROWS

Expensive CONTAINS / ENDS WITH

// Needs TEXT index (RANGE does NOT support these):
CREATE TEXT INDEX person_bio IF NOT EXISTS FOR (n:Person) ON (n.bio)
MATCH (p:Person) WHERE p.bio CONTAINS $keyword RETURN p.name

Over-Traversal — Push LIMIT Early

// Bad: LIMIT after expensive join
MATCH (a:Author)-[:WROTE]->(b:Book)-[:REVIEWED_BY]->(r:Review)
RETURN a.name, b.title, r.text LIMIT 10

// Good: anchor limit before fan-out
MATCH (a:Author)-[:WROTE]->(b:Book)
WITH a, b LIMIT 10
MATCH (b)-[:REVIEWED_BY]->(r:Review)
RETURN a.name, b.title, r.text

Cypher Runtime Selection

RuntimeSelectBest ForAvoid When
pipelinedCYPHER runtime=pipelinedDefault OLTP; streaming, low memoryUnsupported operators fall back to slotted
slottedCYPHER runtime=slottedGuaranteed stable behavior; debugPerformance-critical OLTP
parallelCYPHER 25 runtime=parallelLarge analytical scans; aggregationsOLTP, writes, short queries, Aura Free

Pipelined is default for most queries. Parallel requires dbms.cypher.parallel.worker_limit configured; available on Enterprise and Aura Pro 2025+.

// Force parallel for large aggregation:
CYPHER 25 runtime=parallel
MATCH (n:Transaction) WHERE n.amount > 1000
RETURN n.currency, count(*), sum(n.amount)

Query Monitoring Commands

// Live queries + resource usage:
SHOW QUERIES YIELD query, queryId, elapsedTimeMillis, allocatedBytes, status, username

// Running transactions:
SHOW TRANSACTIONS YIELD transactionId, currentQuery, currentQueryProgress, elapsedTime, status, username, cpuTime, activeLockCount  // currentQueryProgress added [2026.03]

// Kill a specific transaction:
TERMINATE TRANSACTION $transactionId

// Kill a query:
TERMINATE QUERY $queryId

// Graph count stats (node/rel counts by label/type — feed into planner):
CALL db.stats.retrieve('GRAPH COUNTS') YIELD section, data RETURN section, data

// Token stats (label/property/rel-type IDs):
CALL db.stats.retrieve('TOKENS') YIELD section, data RETURN section, data

Full monitoring reference → references/stats-and-monitoring.md


Checklist

  • Run EXPLAIN first — identifies plan problems without execution cost
  • Check for AllNodesScan / NodeByLabelScan — missing index
  • Check for CartesianProduct — missing join predicate
  • Check for Eager — read/write conflict
  • SHOW INDEXES — confirm relevant index exists and state = 'ONLINE'
  • Create missing index; wait for ONLINE
  • Run PROFILE twice — first warms cache, second is representative
  • Compare dbHits before/after fix
  • If estimatedRows wildly off → CALL db.prepareForReplanning()
  • Push LIMIT / WITH n LIMIT k before high-fanout operations
  • For CONTAINS/ENDS WITH — TEXT index, not RANGE
  • For large analytical queries — consider runtime=parallel
  • Kill long-running queries with TERMINATE TRANSACTION

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Authoritative reference for the neo4j-agent-memory Python package — a graph-native memory system for AI agents built on Neo4j — and for the hosted service (NAMS) at memory.neo4jlabs.com. Use this skill whenever the user mentions neo4j-agent-memory, agent memory with Neo4j, context graphs, the POLE+O model, MemoryClient/MemorySettings, the memory MCP server, or any of the framework integrations (LangChain, PydanticAI, CrewAI, AWS Strands, Google ADK, Microsoft Agent Framework, OpenAI Agents, LlamaIndex). Also use when the user mentions the hosted service at memory.neo4jlabs.com, NAMS, the Neo4j Agent Memory Service, the `nams_` API key prefix, or the hosted MCP endpoint. Also use when writing documentation, blog posts, tutorials, PRDs, or code samples for the project, when comparing agent memory approaches, or when positioning graph-native memory against vector-only approaches — even if the user doesn't explicitly name the package.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

Manages Neo4j Aura Agents via the v2beta1 REST API — create, list, get, update, delete, and invoke Aura agents backed by an AuraDB instance. Use when configuring Aura Agent tools (CypherTemplate, SimilaritySearch, Text2Cypher), setting system prompts, deploying agents to REST or MCP endpoints, invoking agents with natural language queries, or generating evaluation datasets (max 50 questions) for the Aura Agent evaluation feature. Covers OAuth2 auth, organization/project scoping, tool parameter schemas, and InvokeAgentResponse format. Does NOT cover AuraDB instance provisioning — use neo4j-aura-provisioning-skill. Does NOT cover vector index creation — use neo4j-vector-index-skill.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

Serverless Aura Graph Analytics (AGA) GDS Sessions — covers GdsSessions, AuraGraphDataScience, AuraAPICredentials, DbmsConnectionInfo, SessionMemory, get_or_create, remote graph projection with gds.graph.project.cypher and gds.graph.project.remote, gds.graph.project.native, gds.graph.construct, graphdatascience client 2.0 session endpoints, async compute and gds.jobs, AuraDB Cypher API memory/sessionId projection, algorithms, write-back, and session lifecycle. Use for AuraDB-connected, self-managed Neo4j, or standalone DataFrame/Spark session workloads. Does NOT cover the embedded GDS plugin on Aura Pro or self-managed Neo4j — use neo4j-gds-skill. Does NOT handle Cypher authoring — use neo4j-cypher-skill. Does NOT cover Snowflake Graph Analytics — use neo4j-snowflake-graph-analytics-skill.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

Provisions and manages Neo4j Aura instances via CLI (aura-cli v1.7+) or REST API. Use when creating, pausing, resuming, resizing, or deleting AuraDB Free/Professional/Business Critical/VDC instances; downloading credentials; scripting CI/CD pipelines; polling async status; or using the Terraform neo4j-labs/neo4jaura provider. Covers auth setup (client credentials OAuth2), credential lifecycle (download once — never recoverable), instance type selection, region codes, and Python provisioning scripts. Does NOT handle Cypher queries — use neo4j-cypher-skill. Does NOT cover Graph Data Science algorithms — use neo4j-gds-skill or neo4j-aura-graph-analytics-skill. Does NOT cover neo4j-admin/cypher-shell — use neo4j-cli-tools-skill.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

Use when working with Neo4j command-line tools — neo4j-cli (modern unified CLI — Cypher via Bolt, schema inspection, Aura management, Docker containers, credential management, agent skill catalog install; install with curl -sSfL https://neo4j.sh/install.sh | bash), neo4j-admin (backup, restore, import, memory sizing), cypher-shell (ad-hoc queries, scripting, CI/CD), or neo4j-mcp (quick MCP server install). Does NOT cover Cypher query authoring — use neo4j-cypher-skill. Does NOT cover driver upgrades — use neo4j-migration-skill. Does NOT cover full MCP editor configuration — use neo4j-mcp-skill.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

Generates, optimizes, and validates Cypher 25 queries for Neo4j 2025.x and 2026.x. Use when writing new Cypher queries, optimizing slow queries, graph pattern matching, vector or fulltext search, subqueries, or batch writes. Covers MATCH, MERGE, CREATE, WITH, RETURN, CALL, UNWIND, FOREACH, LOAD CSV, SEARCH, expressions, functions, indexes, and subqueries. Does NOT handle driver migration or API changes — use neo4j-migration-skill. Does NOT cover DB administration or server ops — use neo4j-cli-tools-skill.

日本語の概要は準備中です。原文の説明を表示しています。

neo4j-contrib/neo4j-skills1142026年10月12日 更新

neo4j-contrib のスキルをすべて見る

このスキルの問題を報告する