Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJJ9a-0005a2-Az for pgsql-performance@arkaria.postgresql.org; Sat, 12 Oct 2019 15:17:58 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iJJ8b-0006wn-1E for pgsql-performance@arkaria.postgresql.org; Sat, 12 Oct 2019 15:16:57 +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_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJJ8a-0006wK-ND for pgsql-performance@lists.postgresql.org; Sat, 12 Oct 2019 15:16:56 +0000 Received: from lungold.riddles.org.uk ([82.68.208.19]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJJ8Y-0002bW-5B for pgsql-performance@postgresql.org; Sat, 12 Oct 2019 15:16:56 +0000 Received: from [192.168.127.1] (port=18781 helo=caithnard.riddles.org.uk) by lungold.riddles.org.uk with esmtp (Exim 4.92.3 (FreeBSD)) (envelope-from ) id 1iJJ8V-0009Id-2I; Sat, 12 Oct 2019 15:16:51 +0000 Received: from localhost ([127.0.0.1]:51637 helo=caithnard.riddles.org.uk) by caithnard.riddles.org.uk with esmtp (Exim 4.92.1 (FreeBSD)) (envelope-from ) id 1iJJ8U-0009Fy-Ts; Sat, 12 Oct 2019 15:16:51 +0000 From: Andrew Gierth To: Ivan Voras Cc: postgres performance list Subject: Re: Optimising a two column OR check In-Reply-To: (Ivan Voras's message of "Sat, 12 Oct 2019 16:39:56 +0200") Message-ID: <87a7a6xamw.fsf@news-spur.riddles.org.uk> References: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (berkeley-unix) Date: Sat, 12 Oct 2019 16:16:50 +0100 MIME-Version: 1.0 Content-Type: text/plain List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk >>>>> "Ivan" == Ivan Voras writes: Ivan> Hello, Ivan> There's a "users" table with the following structure: Ivan> CREATE TABLE "user" ( Ivan> id SERIAL PRIMARY KEY, Ivan> -- other fields Ivan> ); Ivan> and there's a "friends" table with the following structure: Ivan> CREATE TABLE friend ( Ivan> user1_id INTEGER NOT NULL REFERENCES "user"(id), Ivan> user2_id INTEGER NOT NULL REFERENCES "user"(id), Ivan> -- other fields Ivan> CHECK (user1_id < user2_id), Ivan> PRIMARY KEY (user1_id, user2_id) Ivan> ); Ivan> And I'm running this query: Ivan> SELECT user1_id,user2_id FROM friend WHERE user1_id=42 OR user2_id=42; To get friends of user 42: SELECT user1_id FROM friend WHERE user2_id=42 UNION ALL SELECT user2_id FROM friend WHERE user1_id=42; assuming you create the (user2_id,user1_id) index, this should get you an Append of two index-only scans. We can use UNION ALL here rather than UNION because the table constraints ensure there are no duplicates. -- Andrew (irc:RhodiumToad)