Received: from magus.postgresql.org ([87.238.57.229]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1TLivZ-0005FA-JP for pgsql-performance@postgresql.org; Tue, 09 Oct 2012 23:09:29 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1TLivV-0007h1-V8 for pgsql-performance@postgresql.org; Tue, 09 Oct 2012 23:09:29 +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 q99N9LP0009076; Tue, 9 Oct 2012 19:09:22 -0400 (EDT) From: Tom Lane To: Tomas Vondra cc: pgsql-performance@postgresql.org Subject: Re: Why am I getting great/terrible estimates with these CTE queries? In-reply-to: <5074A36B.7060202@fuzzy.cz> References: <5074A36B.7060202@fuzzy.cz> Comments: In-reply-to Tomas Vondra message dated "Wed, 10 Oct 2012 00:21:31 +0200" Date: Tue, 09 Oct 2012 19:09:21 -0400 Message-ID: <9075.1349824161@sss.pgh.pa.us> X-Pg-Spam-Score: -4.0 (----) X-Archive-Number: 201210/97 X-Sequence-Number: 48056 Tomas Vondra writes: > I've been fighting with some CTE queries recently, and in the end I've > ended up with two basic cases. In one case the CTEs work absolutely > great, making the estimates much more precise, while in the other the > results are pretty terrible. And I'm not sure why both of these behave > the way they do. You're assuming the case where the estimate is better is better for a reason ... but it's only better as a result of blind dumb luck. The outer-level query planner doesn't know anything about the CTE's output except the estimated number of rows --- in particular, it doesn't drill down to find any statistics about the join column. So what you're getting there is a default selectivity estimate that just happens to match reality in this case. (If you work through the math in eqjoinsel_inner for the case where the relation sizes are grossly different and we don't have MCV stats, you'll find that it comes out to be assuming that each row in the larger relation has one join partner in the smaller one, which indeed is your situation here.) In the other example, you're likewise getting a default selectivity estimate, only it doesn't match so well, because the default does not include assuming that the join keys are unique on both sides. Without the CTEs, the optimizer can see the keys are unique so it makes the right selectivity estimate. In principle we could make the optimizer try to drill down for stats, which would make these examples work the same with or without the CTE layers. I'm not sure it's worth the trouble though --- I'm dubious that people would use a CTE for cases that are simple enough for the stats estimates to be worth anything. regards, tom lane