Received: from localhost (unknown [200.46.204.183]) by postgresql.org (Postfix) with ESMTP id C336F2E2D42 for ; Thu, 13 Mar 2008 00:38:12 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 11425-03-2 for ; Thu, 13 Mar 2008 00:38:08 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from www.postnewspapers.com.au (www.postnewspapers.com.au [202.61.230.242]) by postgresql.org (Postfix) with ESMTP id 5D2D82E0382 for ; Thu, 13 Mar 2008 00:38:07 -0300 (ADT) Received: from mail.postnewspapers.com.au (202-89-185-120.static.dsl.amnet.net.au [202.89.185.120]) by www.postnewspapers.com.au (Postfix) with ESMTP id 57507D5369 for ; Thu, 13 Mar 2008 12:38:03 +0900 (WST) Received: from localhost (access [127.0.0.1]) by mail.postnewspapers.com.au (Postfix) with ESMTP id 35D331E0435 for ; Thu, 13 Mar 2008 12:38:03 +0900 (WST) X-Virus-Scanned: Debian amavisd-new at postnewspapers.com.au Received: from mail.postnewspapers.com.au ([127.0.0.1]) by localhost (access.postnewspapers.com.au [127.0.0.1]) (amavisd-new, port 10024) with LMTP id fX27RzTIugPd for ; Thu, 13 Mar 2008 12:38:02 +0900 (WST) Received: from [10.0.0.125] (dhcp-125.localnet [10.0.0.125]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "Craig Ringer", Issuer "POST Certificate Authority" (verified OK)) by mail.postnewspapers.com.au (Postfix) with ESMTP id 975E41E0434 for ; Thu, 13 Mar 2008 12:38:02 +0900 (WST) Message-ID: <47D8A191.6000303@postnewspapers.com.au> Date: Thu, 13 Mar 2008 12:37:53 +0900 From: Craig Ringer User-Agent: Thunderbird 2.0.0.12 (Windows/20080213) MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Repeated execution of identical subqueries X-Enigmail-Version: 0.95.6 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200803/264 X-Sequence-Number: 29218 Hi I've been wondering about postgresql's handling of repeated subqueries in statements for a while, and thought I'd ask here. If the exact same subquery appears in multiple places in a complex query, it seems to be executed separately each time it appears. I'm wondering if there's any way, without moving over to PL/PgSQL, to "collapse" such multiple executions down to a single one. Consider this simplistic example, which while useless demonstrates the issue in a self contained way: explain analyze select (select count(id) from booking) as x where (select count(id) from booking) > 100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- Result (cost=37023.85..37023.86 rows=1 width=0) (actual time=668.922..668.922 rows=1 loops=1) One-Time Filter: ($1 > 100) InitPlan -> Aggregate (cost=18511.92..18511.92 rows=1 width=4) (actual time=335.150..335.150 rows=1 loops=1) -> Seq Scan on booking (cost=0.00..17627.13 rows=353913 width=4) (actual time=0.128..200.147 rows=353913 loops=1) -> Aggregate (cost=18511.92..18511.92 rows=1 width=4) (actual time=333.756..333.756 rows=1 loops=1) -> Seq Scan on booking (cost=0.00..17627.13 rows=353913 width=4) (actual time=0.133..198.261 rows=353913 loops=1) Total runtime: 668.993 ms (8 rows) The query: (select count(id) from booking) is executed twice, even though it's guaranteed by MVCC that the result will be the same in both subqueries. Ideally you'd be able to say something like: select (select count(id) from booking) as x where x > 100; I realize that in this case the query can be rewritten as: select x.c from (select count(id) AS c from booking) as x where x.c > 100; but in more complex queries introducing an additional FROM clause for a single value can be undesirable and/or ugly. Is there any way to get postgresql to detect such repeated query parts and evaluate them only once? -- Craig Ringer