Hi, On 2020-07-27 19:02:56 -0400, Alvaro Herrera wrote: > On 2020-Jul-27, Scott Ribe wrote: > > > > On Jul 27, 2020, at 4:00 PM, Alvaro Herrera <alvhe...@2ndquadrant.com> > > > wrote: > > > > > > I don't quite understand why is it that a table with 1000 partitions > > > means that JIT compiles the thing 1000 times. Sure, it is possible that > > > some partitions have a different column layout, but it seems an easy bet > > > that most cases are going to have identical column layout, and so tuple > > > deforming can be shared. (I'm less sure about sharing a compile of an > > > expression, since the varno would vary. But presumably there's a way to > > > take the varno as an input value for the compiled expr too?) Now I > > > don't actually know how this works so please correct if I misunderstand > > > it. > > > > I'm guessing it's because of inlining. You could optimize a function > > that takes parameters, no problem. But what's happening is inlining, > > with parameters, then optimizing.
No, that's not what happens. The issue rather is that at execution time there's simply nothing tying the partitioned parts of the query together from the executor POV. Each table scan gets its own expressions to evaluate quals etc. That's not a JIT specific thing, it's general. Which then means a partitioned query with a projection and a where clause applying on the partition level has > 2 expressions for each partiton. And they get a separate ExprState and get emitted separately. One issue is that we don't take that into account for costing. The other is the overhead, of course. Even when not JITed, that's a lot of work that we don't actually need, except we don't know which partitions look enough like others that we could reuse another expression. One partial way to address this is to simply add a LLVMAddMergeFunctionsPass() at the beginning of the optimization pipeline. In my testing that can quite drastically cut down on optimization time. But obviously solves the problem only to some degree, since that's not free. > Are you saying that if you crank jit_inline_above_cost beyond this > query's total cost, the problem goes away? FWIW, you can set the cost to -1 and it'll never inline. Greetings, Andres Freund