Thanks for writing the article, and sharing your findings here.

It’s not necessarily the case that EnumerableMergeJoinRule was taking 46% of 
the planning time, even though removing it made the planning process faster. 
Reminds me of that old joke [1] about the scientist who “proved” that spiders 
hear through their legs.

Maybe EnumerableMergeJoinRule wasn’t needed for your query, but would removing 
it would damage another query. In other cases, there might be two rules that 
create the ingredients for a third rule to fire; you could disable either rule 
without ill effects, but disabling both would prevent an optimal plan being 
generated.

You get the picture. The planning process can be more like a biological system 
in a Petri dish than a series of well-ordered steps. I believe this kind of 
software system is sometimes called a “reactor”. And yes, this presents unique 
problems for a profiler.

A couple of things I’d keep an eye on are the size of the queue of matched 
rules, and the number of times each rule fires. Some rules, such as those that 
merge projects onto projects and filters, are doing housekeeping that is 
necessary due to the way Calcite stores relational expressions but isn’t doing 
anything that seems “useful” at a high level.

If you could create a test case (either a junit method or an .iq file with a 
single query) and log a performance bug, I think it would be useful. Someone 
could point an agent at it and ask the agent to “make this query plan faster 
without breaking any other queries”.

Julian

[1] 
https://www.reddit.com/r/Jokes/comments/12nvzi/my_dads_favourite_joke_mine_too/ 

> On Oct 28, 2026, at 5:26 AM, Andrey Minogin <[email protected]> wrote:
> 
> Hi all,
> 
> I'd like to share an article that may be of interest here, since it is
> about profiling the Calcite planner:
> 
> The flame graph was wrong by 57×. So I'm building a profiler.
> https://minogin.com/the-flame-graph-was-wrong-by-57x-so-im-building-a-profiler/
> 
> In my workload, ConverterRule.onMatch took about half of the planning time.
> A stack-sampling flame graph put EnumerableMergeJoinRule at 0.81% of
> samples, while measuring per rule gave about 46% of planning time. About
> twenty rules inherit onMatch without overriding it, so the stack frames
> can't tell them apart, and the expensive part of each firing (transformTo
> and the re-registration that follows) runs after convert returns, under the
> base class frame.
> 
> This is not a bug report: the workload had nothing sorted for merge join to
> exploit, so it says nothing against the rule itself. But it may be useful
> to anyone profiling planner performance with stack-based tools.
> 
> Best regards,
> 
> *Andrey Minogin*
> Software architect
> minogin.com

Reply via email to