Skip to content

Conversation

@MathiasVP
Copy link
Collaborator

This query was performing quite poorly on a large internal Microsoft C++ project. The issue was mostly due to bad magic insertion by the compiler in a transitive closure of the ControlFlow.getAPredecessor relation:

Pipeline standard for #ControlFlowGraph::ControlFlowNode.getAPredecessor/0#dispred#66a914dePlus#bf@76b449h2 was evaluated in 35669 iterations totaling 40260223ms (delta sizes total: 8417953207).
        8425040784  ~1%    {2} r1 = SCAN `#ControlFlowGraph::ControlFlowNode.getAPredecessor/0#dispred#66a914dePlus#bf#prev_delta` OUTPUT In.1, In.0
        8497419231  ~1%    {2}    | JOIN WITH `ConstantExprs::successors_adapted/2#5704f996_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1
        8417960656  ~1%    {2}    | AND NOT `#ControlFlowGraph::ControlFlowNode.getAPredecessor/0#dispred#66a914dePlus#bf#prev`(FIRST 2)
                           return r1

It should not take 12 hours to evaluate this predicate 😅. And the Plus#bf part of the name tells me 2 things:

  • It's a transitive closure (i.e., use of * or +) on some relation. In this case the relation is ControlFlowNode.getAPredecessor.
  • The first argument is bounded by magic.

I never really trust the magic inserted by the compiler in such transitive closures. However, as the query is currently written it needs some magic to even be feasible to execute. So I decided to rewrite it and bring in all the magic "manually".

The gist of the problem is all the uses of a = b.getAPredecessor*() in the query. In order for that to perform well we need some bounds on the "end points" of that relation (i.e., a and b). So I define a small little parameterized module that allows you to specify these end-points up-front, and then I do the usual forward/reverse pruning that we've seen so many times.

That's all done in the first commit. The next three rewrites the query to make use of this new module in various parts of the query.

The end result? The query executes in 34 seconds on the same DB 🎉

@MathiasVP MathiasVP merged commit 2515b12 into main Dec 2, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants