Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 20809EA3551 for ; Fri, 13 Jul 2012 14:41:12 -0300 (ADT) Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1Spjrb-0006XX-1p for pgsql-performance@postgresql.org; Fri, 13 Jul 2012 17:41:11 +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 q6DHev9I005525; Fri, 13 Jul 2012 13:40:57 -0400 (EDT) From: Tom Lane To: Eoghan Murray cc: pgsql-performance@postgresql.org Subject: Re: Poor performance problem with Materialize, 8.4 -> 9.1 (enable_material) In-reply-to: References: Comments: In-reply-to Eoghan Murray message dated "Fri, 13 Jul 2012 15:11:23 +0100" Date: Fri, 13 Jul 2012 13:40:57 -0400 Message-ID: <5524.1342201257@sss.pgh.pa.us> X-Pg-Spam-Score: -1.9 (-) X-Archive-Number: 201207/175 X-Sequence-Number: 47356 Eoghan Murray writes: > I'm upgrading from 8.4 to 9.1 and experiencing a performance degradation on > a key query with 2 views and 2 tables. I think the core of the problem is the lousy rowcount estimate for the result of the edited_stop_2 view: when you've got 1 row estimated and almost 10000 rows actual, it's almost guaranteed that the rest of the plan is going to be bad. It's pure luck that 8.4 chooses a plan that fails to suck, because it's optimizing for the wrong case. 9.1 isn't so lucky, but that doesn't make 9.1 broken, just less lucky. I'm not terribly disappointed that that rowcount estimate is bad, because this seems like a rather weird and inefficient way to do "get the rows with the maximal "updated" values". I'd suggest experimenting with some other definitions for edited_stop_2, such as using a subquery: SELECT ... FROM stop o WHERE updated = (select max(updated) from stop i where o.node_id = i.node_id and ...); This might be reasonably efficient given your pkey index for "stop". Or if you don't mind using a Postgres-ism, you could try DISTINCT ON: SELECT DISTINCT ON (node_id, org_id, edge_id, stop_pos) ... FROM stop ORDER BY node_id DESC, org_id DESC, edge_id DESC, stop_pos DESC, updated DESC; See the "weather reports" example in our SELECT reference page for some explanation of how that works. Again, the ORDER BY is chosen to match your pkey index; I'm not sure that the planner will think a full-index scan beats a seqscan-and-sort, but you may as well give it the option. Of these, I would bet that the first will work better if your typical usage is such that only a few rows need to be fetched from the view. I believe the DISTINCT ON is likely to act as an optimization fence forcing the whole view to be evaluated when using the second definition. regards, tom lane