Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASK: Early termination of findDescendantNodes with limit1 #5436

Draft
wants to merge 1 commit into
base: 9.0
Choose a base branch
from

Conversation

mhsdesign
Copy link
Member

@mhsdesign mhsdesign commented Jan 12, 2025

Upgrade instructions

Review instructions

Checklist

  • rector find usages with get 0 to the new fq using limit
  • [ ]

@mhsdesign
Copy link
Member Author

As shown by benchmarks in #4205 (comment) the early termination doesnt have a real impact ...

i think its because we traverse the tree not level by level but each line after line which does not make the happy case that happy in general. Like in my testing i traversed 6001 instead of 6854 nodes to find a node on third level which is still too much.

@mhsdesign
Copy link
Member Author

After a little debugging denny and me found out that the used attempt for termination does not work as expected:

WITH RECURSIVE tree AS
    (SELECT n.*,
         h.subtreetags,
         CAST("ROOT" AS CHAR(50)) AS parentNodeAggregateId,
         0 AS level,
         0 AS position,
         CASE
             WHEN n.nodetypename IN (:explicitlyAllowedNodeTypeNames) THEN 1
             ELSE 0 END AS isMatch
     FROM cr_default_p_graph_node n
              INNER JOIN cr_default_p_graph_hierarchyrelation h
                         ON h.childnodeanchor = n.relationanchorpoint
              INNER JOIN cr_default_p_graph_node p ON p.relationanchorpoint = h.parentnodeanchor
              INNER JOIN cr_default_p_graph_hierarchyrelation ph
                         ON ph.childnodeanchor = p.relationanchorpoint
     WHERE (h.contentstreamid = :contentStreamId)
       AND (h.dimensionspacepointhash = :dimensionSpacePointHash)
       AND (ph.contentstreamid = :contentStreamId)
       AND (ph.dimensionspacepointhash = :dimensionSpacePointHash)
       AND (p.nodeaggregateid = :entryNodeAggregateId)
       AND (NOT JSON_CONTAINS_PATH(h.subtreetags, 'one', :tagPath0))
     UNION
     SELECT cn.*,
         h.subtreetags,
         pn.nodeaggregateid AS parentNodeAggregateId,
         pn.level + 1 AS level,
         h.position,
         CASE
             WHEN cn.nodetypename IN (:explicitlyAllowedNodeTypeNames) THEN 1
             ELSE 0 END AS isMatch
     FROM tree pn
              INNER JOIN cr_default_p_graph_hierarchyrelation h
                         ON h.parentnodeanchor = pn.relationanchorpoint
              INNER JOIN cr_default_p_graph_node cn ON cn.relationanchorpoint = h.childnodeanchor
     WHERE (h.contentstreamid = :contentStreamId)
       AND (h.dimensionspacepointhash = :dimensionSpacePointHash)
       AND (pn.isMatch = 0)
       AND (NOT JSON_CONTAINS_PATH(h.subtreetags, 'one', :tagPath0)))
SELECT *
FROM tree n
WHERE n.isMatch = 1
ORDER BY level ASC, position ASC
LIMIT 1

only the AND (pn.isMatch = 0) is the termination condition and results in the behaviour of not traversing the children further of a matched node. But they dont prevent traversal if the node was already found in another branch.

@mhsdesign
Copy link
Member Author

cc @kitsunet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant