Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1a9EYg-0007Y3-Ql for pgsql-hackers@arkaria.postgresql.org; Wed, 16 Dec 2015 16:04:07 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1a9EYf-0000gC-A4 for pgsql-hackers@arkaria.postgresql.org; Wed, 16 Dec 2015 16:04:05 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1a9EXK-0007ai-V3 for pgsql-hackers@postgresql.org; Wed, 16 Dec 2015 16:02:43 +0000 Received: from mail-wm0-x22b.google.com ([2a00:1450:400c:c09::22b]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1a9EXD-0001Vd-QR for pgsql-hackers@postgresql.org; Wed, 16 Dec 2015 16:02:42 +0000 Received: by mail-wm0-x22b.google.com with SMTP id p187so7460001wmp.0 for ; Wed, 16 Dec 2015 08:02:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=WxX6+rnTdaoh7eFJIT10v8Z16u/JjQNyL9JlEx10Owg=; b=WAJ+id9a9BpkzfC9eG5+B/N0rogoO61mFb3Irad8uz4nF7LxNbH2eoiYJLndNPrp9w S2uXdppwYnaBOafc5d+z8XKr/JHRYST+/JIHQT7E8Sa5wwqUlVjD2+9YZEOPFFRO6Hie jkPp8RtHLtQRJyRyKApvjN7XRk+BdHuTM24TEjgDm0Sr6rpIMsOOv2FhNfDVxOTZqZaB v1feXjBkvOrUASqdMXnnTiMkct62tW+hYfJlYJehzom4o8m0chZd66Rnx7JUi91vBVw0 gPW6wSzmxPiYLxz7WFmej8Jqz8xUDOSk5TO8kXBfyDZ1XVUPwWnwwbt06IPA3vvkiRYI nHEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=WxX6+rnTdaoh7eFJIT10v8Z16u/JjQNyL9JlEx10Owg=; b=d9HCbzeJI3DI4kP/6uU7euuwWmGixDfmWvu/YsNOcyPQiLxYKP680i+dULtf/6ZUQk OkM6vofER+XpyKa2kv+6bG4k5vOlrxAc3R4r7zBPWpTi94eVFQY4EgrAADMzSCA2q7Ki SaKXQF2I1PjIEZceBT6oheszp6NoGeUPrRhQhp1jqL4PLiUY3faLVnyNTPP2FjJmWINb 3qaSHSewl5DZ6PcpPM+dAPgnEJryn1rq3l5e2nfqkDfGYVDqwigr74XaDAt40KtJP5gI GlTzPcIg/fQO7syDxHSgtTkIm5gVitxJHr/eBLeErf8DYPjkq+5mVPBEtGT/eA71CoQm tyag== X-Gm-Message-State: ALoCoQnTdHNjcksLQsq9SBRHaxZTo6GgaUaHaLO6h0GgT8RPN935+s4h9TneSSYkcMJM5Kg92kiYtPA7fXHTO86DsgmU+WIF9DLX0Ddb27OHvfl+Lilg2xKvDzR3GMQb2bRpjhLFCC/rXDpYXTOv7QDvh7tMZUFJBPmpZG03PbuzSwB4ve0ki4YiW+7/RhcIzcHCF3ueMQm2m70QIeUuSioRWkecar3Q+A== X-Received: by 10.28.177.10 with SMTP id a10mr12175969wmf.4.1450281752861; Wed, 16 Dec 2015 08:02:32 -0800 (PST) Received: from [10.137.1.13] (ip-78-45-216-26.net.upcbroadband.cz. [78.45.216.26]) by smtp.gmail.com with ESMTPSA id n7sm7944497wmf.21.2015.12.16.08.02.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Dec 2015 08:02:31 -0800 (PST) Subject: Re: Performance improvement for joins where outer side is unique To: David Rowley , Tom Lane References: <20150320.121140.148610378.horiguchi.kyotaro@lab.ntt.co.jp> <27152324.eFKJb4Khb5@dinodell> <8608754a32d1325c2f83ba8b1df71585@xs4all.nl> <55DA1F9F.5040204@2ndquadrant.com> <5085.1440375543@sss.pgh.pa.us> <8907.1440383377@sss.pgh.pa.us> Cc: PostgreSQL-development From: Tomas Vondra Message-ID: <56718B15.6060507@2ndquadrant.com> Date: Wed, 16 Dec 2015 17:02:29 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.6 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org Hi, On 12/16/2015 01:27 AM, David Rowley wrote: > > I've attached a rebased patch against current master as there were > some conflicts from the recent changes to LATERAL join. Thanks. I've looked at the rebased patch and have a few minor comments. 0) I know the patch does not tweak costing - any plans in this direction? Would it be possible to simply use the costing used by semijoin? 1) nodeHashjoin.c (and other join nodes) I've noticed we have this in the ExecHashJoin() method: /* * When the inner side is unique or we're performing a * semijoin, we'll consider returning the first match, but * after that we're done with this outer tuple. */ if (node->js.unique_inner) node->hj_JoinState = HJ_NEED_NEW_OUTER; That seems a bit awkward because the comment speaks about unique joins *OR* semijoins, but the check only references unique_inner. That of course works because we do this in ExecInitHashJoin(): switch (node->join.jointype) { case JOIN_SEMI: hjstate->js.unique_inner = true; /* fall through */ Either some semijoins may not be unique - in that case the naming is misleading at best, and we either need to find a better name or simply check two conditions like this: if (node->js.unique_inner || node->join.type == JOIN_SEMI) node->hj_JoinState = HJ_NEED_NEW_OUTER; Or all semijoins are unique joins, and in that case the comment may need rephrasing. But more importantly, it begs the question why we're detecting this in the executor and not in the planner? Because if we detect it in executor, we can't use this bit in costing, for example. FWIW the misleading naming was actually mentioned in the thread by Horiguchi-san, but I don't see any response to that (might have missed it though). 2) analyzejoins.c I see that this code in join_is_removable() innerrel = find_base_rel(root, innerrelid); if (innerrel->reloptkind != RELOPT_BASEREL) return false; was rewritten like this: innerrel = find_base_rel(root, innerrelid); Assert(innerrel->reloptkind == RELOPT_BASEREL); That suggests that previously the function expected cases where reloptkind may not be RELOPT_BASEREL, but now it'll error out int such cases. I haven't noticed any changes in the surrounding code that'd guarantee this won't happen, but I also haven't been able to come up with an example triggering the assert (haven't been trying too hard). How do we know the assert() makes sense? 3) joinpath.c - either "were" or "been" seems redundant /* left joins were already been analyzed for uniqueness in mark_unique_joins() */ 4) analyzejoins.c comment format broken /* * mark_unique_joins Analyze joins in order to determine if their inner side is unique based on the join condition. */ 5) analyzejoins.c missing line before the comment } /* * rel_supports_distinctness * Returns true if rel has some properties which can prove the relation * to be unique over some set of columns. * regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers