Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UFCaX-00042x-JX for pgsql-performance@arkaria.postgresql.org; Mon, 11 Mar 2013 23:57:05 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1UFCaV-00077P-QU for pgsql-performance@arkaria.postgresql.org; Mon, 11 Mar 2013 23:57:03 +0000 Received: from makus.postgresql.org ([2001:4800:7903:4::125]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UFCaU-00077J-Oo for pgsql-performance@postgresql.org; Mon, 11 Mar 2013 23:57:02 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UFCaT-0001eX-5Y for pgsql-performance@postgresql.org; Mon, 11 Mar 2013 23:57:02 +0000 Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.5/8.14.5) with ESMTP id r2BNuxEw001455; Mon, 11 Mar 2013 19:56:59 -0400 (EDT) From: Tom Lane To: sthomas@optionshouse.com cc: "pgsql-performance@postgresql.org" Subject: Re: Slow query when used in a view In-reply-to: <513E5AB9.4010809@optionshouse.com> References: <513E5AB9.4010809@optionshouse.com> Comments: In-reply-to Shaun Thomas message dated "Mon, 11 Mar 2013 17:29:13 -0500" Date: Mon, 11 Mar 2013 19:56:59 -0400 Message-ID: <1454.1363046219@sss.pgh.pa.us> X-Pg-Spam-Score: -4.3 (----) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org Shaun Thomas writes: > A developer was complaining about a view he created to abstract an added > column in a left join. ... > Curious, I whipped up this test case: > CREATE VIEW v_slow_view AS > SELECT foo.*, tf.small_label IS NOT NULL AS has_small_label > FROM foo > LEFT JOIN tiny_foo tf USING (small_label); > SELECT bar.*, foo.*, tf.small_label IS NOT NULL AS has_small_label > FROM bar > LEFT JOIN foo ON (foo.id = bar.foo_id) > LEFT JOIN tiny_foo tf USING (small_label) > WHERE bar.id IN (750, 1750, 2750) > ORDER BY bar.id; > SELECT bar.*, sv.* > FROM bar > LEFT JOIN v_slow_view sv ON (sv.id = bar.foo_id) > WHERE bar.id IN (750, 1750, 2750) > ORDER BY bar.id; These queries are not actually equivalent. In the first one, it is impossible for "has_small_label" to read out as NULL: it will either be true or false. However, in the second one, the IS NOT NULL is evaluated below the LEFT JOIN to "sv", and therefore it is required that the query return NULL for "has_small_label" in any row where bar.foo_id lacks a join partner. To implement that behavior correctly, we're forced to form the foo-to-tiny_foo join first, then do the left join with bar (which'll replace RHS columns by nulls where necessary). And that means that you get the inefficient plan wherein the foo-to-tiny_foo join is computed in its entirety. 9.2 does this case better, by virtue of the "parameterized plan" stuff, which exists specifically to let us use nestloop-with-inner-indexscan plans even when there are some join order restrictions complicating matters. regards, tom lane -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance