PROFILE and EXPLAIN

PROFILE = the only honest comparison between two query rewrites.

0/2 done

Overview

PROFILE and EXPLAIN

PROFILE = the only honest comparison between two query rewrites.

Why it matters

Cypher gives you two introspection tools: EXPLAIN (the plan, no execution) and PROFILE (the plan + actual db hits per operator). Decisions get made on db hits, not on intuition.

Going deeper

The four operators that tell you almost everything when you read a PROFILE plan:

OperatorHealthy signalSmell
NodeIndexSeekThe first thing you see; small db hitsMissing → you got a NodeByLabelScan instead
NodeByLabelScanAcceptable on tiny labels (< 10k)Catastrophic on big labels; add an index
Expand(All)Bounded by relationship type + directionUnbounded fan-out on dense node → mis-modelled
EagerSometimes unavoidable on writesOften hides a query that could be split in two; flips reads to materialise the whole result set

A 10× query rewrite is almost always one of: switching a Scan to a Seek (add the right index), constraining a relationship type/direction, or splitting an Eager query into two cheaper ones.

Analogy

EXPLAIN and PROFILE are the dyno and the road test for a car engine.

EXPLAIN is the dyno: 'here's the plan I would execute, here are the operators, the estimated rows at each stage' — it doesn't actually run, so it's safe to use on giant queries. Useful for confirming the planner picked the right index before you ship.

PROFILE is the road test: it runs the query for real and reports actual db hits per operator. The dyno tells you how the engine should perform; the road test tells you how it does. Optimisation decisions live on PROFILE numbers, not on EXPLAIN estimates or stopwatch times.

Make it stick

Use the prompts below to anchor profile and explain to a real graph you own.

  • Pick your slowest production query. PROFILE it — which operator owns the most db hits, and what's the indicated fix (index? relationship constraint? Eager split)?
  • Where are tuning decisions in your team made on wall-clock instead of db hits? That's an unreliable optimisation loop.
  • Which query in your codebase has *never* been PROFILEd? That's almost certainly the next big win.

Reading in progress · 0 of 2 activities done