Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qMHGR-0021BJ-V0 for pgsql-bugs@arkaria.postgresql.org; Thu, 20 Jul 2023 00:11:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qMHGQ-00D6NW-Gj for pgsql-bugs@arkaria.postgresql.org; Thu, 20 Jul 2023 00:11:26 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qMHGQ-00D6NO-8X for pgsql-bugs@lists.postgresql.org; Thu, 20 Jul 2023 00:11:26 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qMHGM-000XTx-MF for pgsql-bugs@lists.postgresql.org; Thu, 20 Jul 2023 00:11:25 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 36K0BIuv458888; Wed, 19 Jul 2023 20:11:18 -0400 From: Tom Lane To: David Rowley cc: zuming.jiang@inf.ethz.ch, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #18030: Large memory consumption caused by in-clause subqueries In-reply-to: References: <18030-2a563b7ccc7d6152@postgresql.org> Comments: In-reply-to David Rowley message dated "Thu, 20 Jul 2023 11:13:05 +1200" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <458886.1689811878.1@sss.pgh.pa.us> Date: Wed, 19 Jul 2023 20:11:18 -0400 Message-ID: <458887.1689811878@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk David Rowley writes: > When I looked at this at first, I just thought it was a problem > because of the huge values you're passing to lpad, but on looking > again, I don't quite see why we need to keep the result of the lpad > around for the entire execution of the subquery. I wonder if we're > missing a ResetExprContext(econtext) inside ExecScanSubPlan(). > The following example is a bit easier to follow: > explain analyze select * from (values(1),(2)) v(v) where lpad(v::text, > 1024*1024) in (select 'test' from generate_series(1,1000) where v.v > > 0); > Currently, this will consume around 1GB of memory due to executing the > lpad once for each row of the subquery. But isn't it ok to just reset > the tuple context after fetching each row from the subquery? That > would mean we'd only allocate around 1MB at a time instead of 1GB. I doubt that that's okay, because if we are passing any pass-by-ref params to the subquery (cf. loop loading ecxt_param_exec_vals[] at nodeSubplan.c:257ff), this change would zap them. But perhaps it is worth setting up a second, shorter-lived context to evaluate the per-row comparison expression in? I also wonder if we could avoid evaluating the lpad() for each row in the first place. This'd require breaking down the comparison expression more finely than we do now. But certainly the average user would be surprised that we evaluate lpad() per-subquery-row. regards, tom lane