You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every CypherEngine.execute() call parses, analyses and plans the query from scratch, even when only the parameters change. Parameters can't be bound to an existing plan, because semantic analysissubstitutes them into the AST as literals before planning. execute() then plans the substituted query each time.
Applications, and the LDBC Interactive workload itself, run the same query text many times with different parameters, so planning cost is paid on every call.
Evidence
On SF1, in memory, explain() (which plans but doesn't execute) takes a large share of the total query time:
Query
execute()
explain()
IC7
21.1 ms
15.4 ms
IC11
5.0 ms
3.4 ms
IC13
4.5 ms
0.8 ms
explain() also formats the plan text, so these overstate planning time; the first step of this issue is to measure parse, analysis, logical and physical planning separately. On the 30-query workload, lance-csr's fastest queries sit at about 0.5 ms while FalkorDB and Neo4j reach 0.2 ms, which suggests a fixed per-query overhead (results).
Suggested fix
Instrument the stages and report where the time goes.
Cache the plan for a query text: keep parameters as placeholders through planning (DataFusion supports Expr::Placeholder and LogicalPlan::with_param_values), and bind values at execution. Invalidate the cache on refresh(), since statistics and the CSR change.
Where a parameter changes the plan shape (for example, it feeds pattern ordering by selectivity), either keep it as a literal for that query or key the cache on it.
Acceptance criteria
A breakdown of planning stages for the IC queries, in the pull request.
Repeated execute() calls with the same text and different parameters reuse the plan, with results identical to fresh planning.
refresh() invalidates cached plans; a test covers a query before and after a refresh.
Benchmarks show the effect on IC7, IC11 and the 30-query workload's fastest queries.
Identified by profiling the LDBC IC benchmark; plan caching has not been prototyped.
Addressed on main by #55. CypherEngine now keeps unoptimized plan templates per catalog snapshot and rebinds scalar parameters into them (engine.rs, CypherQuery::prepare_cached_plan in query.rs). A refresh starts with an empty cache, a different parameter type gets its own template, and parameters that change the plan shape (row counts, CALL) skip the cache. Tests: cached_templates_rebind_scalars_and_preserve_schema, cached_templates_respect_catalog_and_parameter_types, parameterized_row_counts_bypass_templates.
Activity
Reuse scalar query templates within each engine snapshot (#34)
feat: integrate cypher, csr and engine work for 0.3.0 (#55)
prrao87 commentedon Oct 27, 2026
Addressed on main by #55.
CypherEnginenow keeps unoptimized plan templates per catalog snapshot and rebinds scalar parameters into them (engine.rs,CypherQuery::prepare_cached_planinquery.rs). A refresh starts with an empty cache, a different parameter type gets its own template, and parameters that change the plan shape (row counts, CALL) skip the cache. Tests:cached_templates_rebind_scalars_and_preserve_schema,cached_templates_respect_catalog_and_parameter_types,parameterized_row_counts_bypass_templates.