Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id C5B331789D23 for ; Wed, 16 Nov 2011 10:06:58 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 12790-03 for ; Wed, 16 Nov 2011 14:06:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0-rc2 Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 0FDC31789D22 for ; Wed, 16 Nov 2011 10:06:53 -0400 (AST) Received: from mail-vx0-f174.google.com ([209.85.220.174]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1RQg8Z-0002Ob-IT for pgsql-performance@postgresql.org; Wed, 16 Nov 2011 14:06:52 +0000 Received: by vcbfk1 with SMTP id fk1so377399vcb.19 for ; Wed, 16 Nov 2011 06:06:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=MWH66S1/JsBs6xB/8pfWT9KfRPd4PDRdDFScFyuwphw=; b=aA0hYmilNlzL8rh6p0C/InJOvmzaXwVt/ZiU31QXETI9ol2a8dT5AR8p4mDn004Uaa jRFN7abe2Y9BMLWWjDGi+yc6KRA6PATZjqdzjeJ+rifBBlddqr6Ym6hYAUkjIYgX/qdA Di9s6NFC31pmnLOXPol1WxeUzheY7v1K0EtXQ= Received: by 10.52.67.144 with SMTP id n16mr50114792vdt.108.1321452398749; Wed, 16 Nov 2011 06:06:38 -0800 (PST) Received: from speedbook-air.home.jay.fm (home.jay.fm. [173.166.48.118]) by mx.google.com with ESMTPS id r5sm43081264vdj.11.2011.11.16.06.06.35 (version=SSLv3 cipher=OTHER); Wed, 16 Nov 2011 06:06:38 -0800 (PST) Message-ID: <4EC3C36A.3020502@gmail.com> Date: Wed, 16 Nov 2011 09:06:34 -0500 From: Jay Levitt User-Agent: Postbox 3.0.1 (Macintosh/20111102) MIME-Version: 1.0 To: Tom Lane CC: Kevin Grittner , Merlin Moncure , pgsql-performance@postgresql.org Subject: Re: Subquery in a JOIN not getting restricted? References: <4EB84CB4.2010102@gmail.com> <4EB7FEFD0200002500042B1C@gw.wicourts.gov> <4EB80CAA0200002500042B3B@gw.wicourts.gov> <4EB86784.7080209@gmail.com> <4EB88C5A.2020704@gmail.com> <4EBA44B70200002500042BC8@gw.wicourts.gov> <4EBA8C100200002500042C23@gw.wicourts.gov> <4EBBD717.80507@gmail.com> <8071.1320938568@sss.pgh.pa.us> In-Reply-To: <8071.1320938568@sss.pgh.pa.us> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.899 tagged_above=-10 required=5 tests=BAYES_00=-1.9, FREEMAIL_FROM=0.001 X-Spam-Level: X-Archive-Number: 201111/194 X-Sequence-Number: 45705 Tom Lane wrote: > Jay Levitt writes: >> If the query was more like > >> select questions.id >> from questions >> join ( >> select sum(u.id) >> from users as u >> group by u.id >> ) as s >> on s.id = questions.user_id >> where questions.id = 1; > >> would you no longer be surprised that it scanned all user rows? > > I'd suggest rephrasing the query to do the join underneath the GROUP BY. Well, my real goal is to have that inner query in a set-returning function that gives a computed table of other users relative to the current user, and then be able to JOIN that with other things and ORDER BY it: select questions.id from questions join (select * from relevance(current_user)) as r on r.id = questions.user_id where questions.id = 1; I assume there's no way for that function (in SQL or PL/pgSQL) to reach to the upper node and say "do that join again here", or force the join order from down below? I can't imagine how there could be, but never hurts to ask. Right now, our workaround is to pass the joined target user as a function parameter and do the JOIN in the function, but that means we have to put the function in the select list, else we hit the lack of LATERAL support: -- This would need LATERAL select questions.id from questions join ( select * from relevance(current_user, questions.user_id)) as r ) on r.id = questions.user_id where questions.id = 1; -- This works but has lots of row-at-a-time overhead select questions.id, ( select * from relevance(current_user, questions.user_id) ) as r from questions where questions.id = 1; Again, just checking if there's a solution I'm missing. I know the optimizer is only asymptotically approaching optimal! Jay