Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 2C832632BBF for ; Sun, 20 Jun 2010 12:21:17 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 43424-03 for ; Sun, 20 Jun 2010 15:21:10 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by mail.postgresql.org (Postfix) with ESMTP id E616C6327EE for ; Sun, 20 Jun 2010 12:21:09 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.2/8.14.2) with ESMTP id o5KFL7W2025117; Sun, 20 Jun 2010 11:21:07 -0400 (EDT) To: "Davor J." cc: pgsql-performance@postgresql.org Subject: Re: Slow function in queries SELECT clause. In-reply-to: References: Comments: In-reply-to "Davor J." message dated "Sat, 19 Jun 2010 21:38:14 +0200" Date: Sun, 20 Jun 2010 11:21:07 -0400 Message-ID: <25116.1277047267@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.011 tagged_above=-10 required=5 tests=BAYES_20=-0.001, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201006/355 X-Sequence-Number: 39211 "Davor J." writes: > Suppose 2 functions: factor(int,int) and offset(int, int). > Suppose a third function: convert(float,int,int) which simply returns > $1*factor($2,$3)+offset($2,$3) > All three functions are IMMUTABLE. You should write the third function as a SQL function, which'd allow it to be inlined. > VERY FAST (half a second): > ---------------- > SELECT data*factor(1,2)+offset(1,2) FROM tbl_data; In this case both factor() calls are folded to constants, hence executed only once. > VERY SLOW (a minute): > ---------------- > SELECT convert(data, 1, 2) FROM tbl_data; Without inlining, there's no hope of any constant-folding here. The optimizer just sees the plpgsql function as a black box and can't do anything with it. BTW, your later mail shows that the factor() functions are not really IMMUTABLE, since they select from tables that presumably are subject to change. The "correct" declaration would be STABLE. If you're relying on constant-folding to get reasonable application performance, you're going to have to continue to mislabel them as IMMUTABLE; but be aware that you're likely to have issues any time you do change the table contents. The changes won't get reflected into existing query plans. regards, tom lane