Re: to_jsonb performance on array aggregated correlated subqueries

Nico Heller <nico.heller@posteo.de>

From: Nico Heller <nico.heller@posteo.de>
To: Rick Otten <rottenwindfish@gmail.com>
Cc: pgsql-performance@lists.postgresql.org
Date: 2022-08-12T19:18:33Z
Lists: pgsql-performance
Am 12.08.2022 um 21:15 schrieb Rick Otten:
>
>
> On Fri, Aug 12, 2022 at 3:07 PM Nico Heller <nico.heller@posteo.de> wrote:
>
>     Am 12.08.2022 um 21:02 schrieb Rick Otten:
>
>>
>>
>>     On Fri, Aug 12, 2022 at 2:50 PM Nico Heller
>>     <nico.heller@posteo.de> wrote:
>>
>>         Good day,
>>
>>         consider the following query:
>>
>>         WITH aggregation(
>>              SELECT
>>                     a.*,
>>                    (SELECT array_agg(b.*) FROM b WHERE b.a_id = a.id
>>         <http://a.id>) as "bs",
>>                    (SELECT array_agg(c.*) FROM c WHERE c.a_id = a.id
>>         <http://a.id>) as "cs",
>>                    (SELECT array_agg(d.*) FROM d WHERE d.a_id = a.id
>>         <http://a.id>) as "ds",
>>                    (SELECT array_agg(e.*) FROM d WHERE e.a_id = a.id
>>         <http://a.id>) as "es"
>>              FROM a WHERE a.id <http://a.id> IN (<some big list,
>>         ranging from 20-180 entries)
>>         )
>>         SELECT to_jsonb(aggregation.*) as "value" FROM aggregation;
>>
>>
>>     - You do have an index on `b.a_id` and `c.a_id`, etc... ?  You
>>     didn't say...
>     Yes there are indices on all referenced columns of the subselect
>     (they are all primary keys anyway)
>>     - Are you sure it is the `to_jsonb` that is making this query slow?
>     Yes, EXPLAIN ANALYZE shows a doubling of execution time - I don't
>     have numbers on the memory usage difference though
>>
>>     - Since you are serializing this for easy machine readable
>>     consumption outside of the database, does it make a difference if
>>     you use `to_json` instead?
>>
>     Using to_json vs. to_jsonb makes no difference in regards to
>     runtime, I will check if the memory consumption is different on
>     monday - thank you for the idea!
>
>
> One other thought.  Does it help if you convert the arrays to json 
> first before you convert the whole row?  ie, add some to_json()'s 
> around the bs, cs, ds, es columns in the CTE.  I'm wondering if 
> breaking the json conversions up into smaller pieces will let the 
> outer to_json() have less work to do and overall run faster.  You 
> could even separately serialize the elements inside the array too.  I 
> wouldn't think it would make a huge difference, you'd be making a 
> bunch of extra to_json calls, but maybe it avoids some large memory 
> structure that would otherwise have to be constructed to serialize all 
> of those objects in all of the arrays all at the same time.

Using jsonb_array_agg and another to_jsonb at the (its still needed to 
create one value at the end and to include the columns "a.*") worsens 
the query performance by 100%, I can't speak for the memory usage 
because I would have to push these changes to preproduction - will try 
this on monday, thanks.