Skip to content

Result-equivalent LadyBugDB queries show a 17.1x runtime gap across double-negated boolean-redundancy variants #668

Description

@YaeSakuraQ

Ladybug version

v0.18.0

What operating system are you using?

Ubuntu 24.04

What happened?

Result-equivalent LadyBugDB queries show a 17.1x runtime gap across double-negated boolean-redundancy variants

I found two result-equivalent LadyBugDB query formulations whose measured runtime differs substantially on the attached graph. The intended difference between the formulations is a double-negated boolean-redundancy variant.

I am reporting the observed runtime/profile difference without assigning it to a specific LadyBugDB component.

Steps to reproduce

  1. Load the attached graph setup file into an empty disposable LadyBugDB database:

reproducer_graph.cypher.txt

while IFS= read -r stmt; do ladybugdb-cypher "$stmt"; done < reproducer_graph.cypher.txt
  1. Verify the graph size:
MATCH (n) RETURN count(n) AS nodes;
-- nodes: 128

MATCH ()-[r]->() RETURN count(r) AS relationships;
-- relationships: 73
  1. Run the fast query:
PROFILE
MATCH (n0),
  (n1 :L5 :L3)<-[r0 :T4]-(n2 :L4 :L0)-[r1 :T5]->(n3 :L2)
WHERE (((r0.id) > -1)
  AND ((r0.id) <> (r1.id)))
UNWIND [(r1.k71), (n1.k30), 1151137086] AS a0
OPTIONAL MATCH (n0),
  (n3)-[r2 :T1]->(n4 :L5 :L2)
WHERE ((r2.id) > -1)
OPTIONAL MATCH (n4 :L4 :L2 :L5)<-[]-(n3)<-[]-(n2)
WHERE (1354844104 = 1354844104)
OPTIONAL MATCH (n2)-[]->(n3)-[]->(n4 :L2),
  (n0)
WHERE ((r1.k70)
  AND (r1.k70))
OPTIONAL MATCH (n4)-[r3 :T0]->(n5)
WHERE (r3.k38)
WITH min('5tP') AS a1,
  collect(-401349781) AS a2
UNWIND [-1523432737, 451047109, 451047109] AS a3
RETURN 0 AS a4
  1. Run the slow query:
PROFILE
MATCH (n0),
  (n1 :L5 :L3)<-[r0 :T4]-(n2 :L4 :L0)-[r1 :T5]->(n3 :L2)
WHERE ((((r0.id) > -1)
  AND ((r0.id) <> (r1.id))))
  AND NOT(NOT(true
  OR (coalesce(n0.id = n0.id,
  true))))
UNWIND [(r1.k71), (n1.k30), 1151137086] AS a0
OPTIONAL MATCH (n0),
  (n3)-[r2 :T1]->(n4 :L5 :L2)
WHERE ((r2.id) > -1)
OPTIONAL MATCH (n4 :L4 :L2 :L5)<-[]-(n3)<-[]-(n2)
WHERE (1354844104 = 1354844104)
OPTIONAL MATCH (n2)-[]->(n3)-[]->(n4 :L2),
  (n0)
WHERE ((r1.k70)
  AND (r1.k70))
OPTIONAL MATCH (n4)-[r3 :T0]->(n5)
WHERE (r3.k38)
WITH min('5tP') AS a1,
  collect(-401349781) AS a2
UNWIND [-1523432737, 451047109, 451047109] AS a3
RETURN 0 AS a4

Expected behavior

The two queries are intended to be result-equivalent. On the same graph, I would expect comparable execution time, or at least not a large runtime gap, between these two formulations.

Actual behavior

Repeated replay confirmed that the two queries returned the same result rows and reported a large runtime gap.

Metric Fast query Slow query
Median runtime 17.736 ms 303.864 ms
Runtime ratio 1.000x 17.132x
Runtime delta n/a 286.127 ms

PROFILE plan comparison

Fast query plan excerpt:

Plan evidence from plan_diff.json for the fast query:
- Barrier count: 7
- Operator-family delta versus the paired query: {"Barrier": -1, "Filter": 2, "Join": -1, "Projection": 0}
- Detailed raw PROFILE output and normalized plan summaries are attached in profile_summaries.json and plan_diff.json.

Slow query plan excerpt:

Plan evidence from plan_diff.json for the slow query:
- Barrier count: 6
- Operator-family delta versus the paired query: {"Barrier": -1, "Filter": 2, "Join": -1, "Projection": 0}
- Detailed raw PROFILE output and normalized plan summaries are attached in profile_summaries.json and plan_diff.json.

Are there known steps to reproduce?

reproducer_graph.cypher.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions