Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id 5B3FFB5DC1E for ; Wed, 26 Oct 2011 06:00:58 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.29]) (amavisd-maia, port 10024) with ESMTP id 71995-10 for ; Wed, 26 Oct 2011 09:00:52 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.8.0-rc2 Received: from ns210619.ovh.net (ns210619.ovh.net [188.165.206.83]) by mail.postgresql.org (Postfix) with ESMTP id 90B7BB5DC13 for ; Wed, 26 Oct 2011 06:00:51 -0300 (ADT) Received: from localhost (localhost.localdomain [127.0.0.1]) by ns210619.ovh.net (Postfix) with ESMTP id B5C053D1E428 for ; Wed, 26 Oct 2011 11:02:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at ns210619.ovh.net Received: from ns210619.ovh.net ([127.0.0.1]) by localhost (ns210619.ovh.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Pf3LL89VD1RX for ; Wed, 26 Oct 2011 11:02:47 +0200 (CEST) Received: from [192.168.1.4] (119.87.220.87.dynamic.jazztel.es [87.220.87.119]) by ns210619.ovh.net (Postfix) with ESMTPA id 1B82D3D1E012 for ; Wed, 26 Oct 2011 11:02:47 +0200 (CEST) Message-ID: <4EA7CC40.9000200@linos.es> Date: Wed, 26 Oct 2011 11:00:48 +0200 From: Linos User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20111001 Thunderbird/7.0.1 MIME-Version: 1.0 CC: pgsql-performance@postgresql.org Subject: Re: CTE vs Subquery References: <4EA6E252.6030002@linos.es> <24672.1319561025@sss.pgh.pa.us> <4EA6E839.6050804@linos.es> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.879 tagged_above=-10 required=5 tests=BAYES_00=-1.9, MISSING_HEADERS=1.021 X-Spam-Level: X-Archive-Number: 201110/215 X-Sequence-Number: 45437 El 25/10/11 19:11, Merlin Moncure escribió: > On Tue, Oct 25, 2011 at 11:47 AM, Linos wrote: >> El 25/10/11 18:43, Tom Lane escribió: >>> Linos writes: >>>> i am having any problems with performance of queries that uses CTE, can the >>>> join on a CTE use the index of the original table? >>> >>> CTEs act as optimization fences. This is a feature, not a bug. Use >>> them when you want to isolate the evaluation of a subquery. >>> >>> regards, tom lane >>> >> >> The truth it is that complex queries seems more readable using them (maybe a >> personal preference no doubt). >> >> Do have other popular databases the same behavior? SQL Server or Oracle for example? > > In my experience, SQL server also materializes them -- basically CTE > is short hand for 'CREATE TEMP TABLE foo AS SELECT...' then joining to > foo. If you want join behavior, use a join (by the way IIRC SQL > Server is a lot more restrictive about placement of ORDER BY). > > I like CTE current behavior -- the main place I find it awkward is in > use of recursive queries because the CTE fence forces me to abstract > the recursion behind a function, not a view since pushing the view > qual down into the CTE is pretty horrible: > > postgres=# explain select foo.id, (with bar as (select id from foo f > where f.id = foo.id) select * from bar) from foo where foo.id = 11; > QUERY PLAN > ------------------------------------------------------------------------------------- > Index Scan using foo_idx on foo (cost=0.00..16.57 rows=1 width=4) > Index Cond: (id = 11) > SubPlan 2 > -> CTE Scan on bar (cost=8.28..8.30 rows=1 width=4) > CTE bar > -> Index Scan using foo_idx on foo f (cost=0.00..8.28 > rows=1 width=4) > Index Cond: (id = $0) > (7 rows) > > whereas for function you can inject your qual inside the CTE pretty > easily. this is a different problem than the one you're describing > though. for the most part, CTE execution fence is a very good thing, > since it enforces restrictions that other features can leverage, for > example 'data modifying with' queries (by far my all time favorite > postgres enhancement). > > merlin > ok, i get the idea, but i still don't understand what Tom says about isolate evaluation, apart from the performance and the readability, if i am not using writable CTE or recursive CTE, what it is the difference in evaluation (about being isolate) of a subquery vs CTE with the same text inside. I have been using this form lately: WITH inv (SELECT item_id, SUM(units) AS units FROM invoices), quo AS (SELECT item_id, SUM(units) AS units FROM quotes) SELECT items.item_id, CASE WHEN inv.units IS NOT NULL THEN inv.units ELSE 0 END AS units_invoices, CASE WHEN quo.units IS NOT NULL THEN quo.units ELSE 0 END AS units_quotes FROM items LEFT JOIN inv ON inv.item_id = items.item_id LEFT JOIN quo ON quo.item_id = items.item_id Well this is oversimplified because i use much more tables and filter based on dates, but you get the idea, it seems that this type of query should use subqueries, no? Regards, Miguel Angel.