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 1vGgDd-0045lL-As for pgsql-performance@arkaria.postgresql.org; Wed, 05 Nov 2025 16:18:44 +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 1vGgDb-003Xtf-Ve for pgsql-performance@arkaria.postgresql.org; Wed, 05 Nov 2025 16:18:43 +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 1vGgDb-003XtU-LX for pgsql-performance@lists.postgresql.org; Wed, 05 Nov 2025 16:18:42 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vGgDY-0069BF-18 for pgsql-performance@lists.postgresql.org; Wed, 05 Nov 2025 16:18:42 +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 5A5GId9c836753; Wed, 5 Nov 2025 11:18:39 -0500 From: Tom Lane To: "Dirschel, Steve" cc: "pgsql-performance@lists.postgresql.org" Subject: Re: Problem getting query to use index inside a function In-reply-to: References: Comments: In-reply-to "Dirschel, Steve" message dated "Wed, 05 Nov 2025 16:02:27 +0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <836751.1762359519.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Wed, 05 Nov 2025 11:18:39 -0500 Message-ID: <836752.1762359519@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk "Dirschel, Steve" writes: > Here is the function I'm having difficulties with: > CREATE OR REPLACE FUNCTION public.steve1(param_requestid text[], param_p= roductid integer DEFAULT 1) > RETURNS TABLE(objectid text, n text, v text, vt integer) > LANGUAGE sql > AS $function$ > SELECT objectid::text > , i->>'n'::text > , i->>'v'::text > , (i->>'vt') :: INT as vt > FROM request r > , jsonb_array_elements(data -> 'i') i > WHERE objectid =3D ANY($1) > AND productid=3D$2 > $function$ > ; > Query: > shared=3D> explain (analyze, buffers) > shared-> SELECT objectid::text, n::text, v::text, vt::int FROM steve1(AR= RAY['5ab8e0ca-abb5-48c9-a95e-2bb2a375d903','adcbe251-6723-48a8-8385-55133f= ab704a'], 1); > QUERY PLAN > ------------------------------------------------------------------------= ---------------------------------------- > Function Scan on steve1 (cost=3D0.25..10.25 rows=3D1000 width=3D100) (a= ctual time=3D42.694..42.942 rows=3D3368 loops=3D1) I think you would have better luck if the planner were "inlining" this function, which we can see it's not since you get a Function Scan on steve1 rather than the contained query. I think the only thing stopping that from happening is that the function is (by default) VOLATILE. Try marking it STABLE so that it can share the calling query's snapshot. (v18 should handle such cases better than previous versions, BTW. But you'd still be better off marking the function STABLE.) regards, tom lane