Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bnK6Y-0006fq-WF for pgsql-performance@arkaria.postgresql.org; Fri, 23 Sep 2016 06:37:03 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1bnK6Y-0004jL-Io for pgsql-performance@arkaria.postgresql.org; Fri, 23 Sep 2016 06:37:02 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1bnK4t-0002tV-DI for pgsql-performance@postgresql.org; Fri, 23 Sep 2016 06:35:19 +0000 Received: from shout02.mail.de ([2001:868:100:600::217]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1bnK4q-00042R-3G for pgsql-performance@postgresql.org; Fri, 23 Sep 2016 06:35:17 +0000 Received: from postfix02.mail.de (postfix02.bt.mail.de [10.0.121.126]) by shout02.mail.de (Postfix) with ESMTP id 65DD15FFBB; Fri, 23 Sep 2016 08:35:12 +0200 (CEST) Received: from smtp04.mail.de (smtp04.bt.mail.de [10.0.121.214]) by postfix02.mail.de (Postfix) with ESMTP id 4DF5DC02F2; Fri, 23 Sep 2016 08:35:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mail.de; s=mail201212; t=1474612512; bh=ws567QcmvfjGRFs29ln5VbtQOfhVo4hkEAspVjRgDTE=; h=Subject:To:References:From:Date:In-Reply-To:From; b=uNCtjlpbblcd8XVlTWzLxbH6K4IPTctQdjSwP+VRsuwNouh0TCg5isklT7lgeDCHc SMQmnZIhI+4PGDOfqnoIvmSX4cE6UgwOlNbb0YuXpgbJ+2yrmp9qcn69Mh+Lj6udwZ hFufgKHSXa+o2BqRaGMy+SKGksUoo5/qYzIBFBnc= Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp04.mail.de (Postfix) with ESMTPSA id 73FCF80007; Fri, 23 Sep 2016 08:35:10 +0200 (CEST) Subject: Re: Multiple-Table-Spanning Joins with ORs in WHERE Clause To: lfischer , pgsql-performance@postgresql.org, jeff.janes@gmail.com, ineyman@perceptron.com, b.n.madusudanan@gmail.com References: <97dbd6f9-a289-94d1-325f-997df87c672a@mail.de> From: "Sven R. Kunze" Message-ID: <0e86e399-61dc-8e78-415e-c83db9592a80@mail.de> Date: Fri, 23 Sep 2016 08:35:09 +0200 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-purgate-size: 2543 X-purgate-ID: 154282::1474612512-00000836-F663957D/0/0 X-Pg-Spam-Score: -5.8 (-----) 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 Thanks a lot Madusudanan, Igor, Lutz and Jeff for your suggestions. What I can confirm is that the UNION ideas runs extremely fast (don't have access to the db right now to test the subquery idea, but will check next week as I travel right now). Thanks again! :) I was wondering: would it be possible for PostgreSQL to rewrite the query to generate the UNION (or subquery plan if it's also fast) on it's own? Thanks, Sven On 22.09.2016 16:44, lfischer wrote: > Hi Sven > > Why not do something like > > SELECT * FROM big_table > WHERE > id in (SELECT big_table_id FROM table_a WHERE "table_a"."item_id" > IN ()) > OR > id in (SELECT big_table_id FROM table_a WHERE "table_b"."item_id" > IN ()) > > that way you don't need the "distinct" and therefore there should be > less comparison going on. > > Lutz > > On 22/09/16 14:24, Sven R. Kunze wrote: >> Hi pgsql-performance list, >> >> >> what is the recommended way of doing **multiple-table-spanning joins >> with ORs in the WHERE-clause**? >> >> >> Until now, we've used the LEFT OUTER JOIN to filter big_table like so: >> >> >> SELECT DISTINCT >> FROM >> "big_table" >> LEFT OUTER JOIN "table_a" ON ("big_table"."id" = >> "table_a"."big_table_id") >> LEFT OUTER JOIN "table_b" ON ("big_table"."id" = >> "table_b"."big_table_id") >> WHERE >> "table_a"."item_id" IN () >> OR >> "table_b"."item_id" IN (); >> >> >> However, this results in an awful slow plan (requiring to scan the >> complete big_table which obviously isn't optimal). >> So, we decided (at least for now) to split up the query into two >> separate ones and merge/de-duplicate the result with application logic: >> >> >> SELECT >> FROM >> "big_table" INNER JOIN "table_a" ON ("big_table"."id" = >> "table_a"."big_table_id") >> WHERE >> "table_a"."item_id" IN (); >> >> >> SELECT >> FROM >> "big_table" INNER JOIN "table_b" ON ("big_table"."id" = >> "table_b"."big_table_id") >> WHERE >> "table_b"."item_id" IN (); >> >> >> As you can imagine we would be very glad to solve this issue with a >> single query and without having to re-code existing logic of >> PostgreSQL. But how? >> >> >> Best, >> Sven >> >> >> PS: if you require EXPLAIN ANALYZE, I can post them as well. >> >> > > -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance