Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cjFEj-00088t-B3 for pgsql-performance@arkaria.postgresql.org; Thu, 02 Mar 2017 01:08:53 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1cjFEi-0001h7-P1 for pgsql-performance@arkaria.postgresql.org; Thu, 02 Mar 2017 01:08:52 +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 1cjFCw-0006tB-ER for pgsql-performance@postgresql.org; Thu, 02 Mar 2017 01:07:02 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1cjFCu-0000T4-1Z for pgsql-performance@postgresql.org; Thu, 02 Mar 2017 01:07:01 +0000 Received: from pro.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id v2216wom004074; Wed, 1 Mar 2017 20:06:58 -0500 From: Tom Lane To: Stefan Andreatta cc: pgsql-performance@postgresql.org Subject: Re: anti-join with small table via text/varchar cannot estimate rows correctly In-reply-to: <4de52c93-68e1-7c4b-86ff-4dc17ae400bb@synedra.com> References: <4de52c93-68e1-7c4b-86ff-4dc17ae400bb@synedra.com> Comments: In-reply-to Stefan Andreatta message dated "Wed, 01 Mar 2017 23:00:06 +0100" Date: Wed, 01 Mar 2017 20:06:58 -0500 Message-ID: <1454.1488416818@sss.pgh.pa.us> X-Pg-Spam-Score: -1.9 (-) 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 Stefan Andreatta writes: > The same anti-join using the text fields, however estimates just 1 > resulting row, while there are still of course 9,999 of them: > =# explain analyze > select tmp_san_1.id > from tmp_san_1 > left join tmp_san_2 on tmp_san_1.text = tmp_san_2.text > where tmp_san_2.id is null; That is not an anti-join. To make it one, you have to constrain the RHS join column to be IS NULL, not some random other column. Note the join type isn't getting shown as Anti: > Hash Left Join (cost=1.02..192.53 rows=1 width=4) (actual time=0.020..3.091 rows=9999 loops=1) As written, the query could return some rows that weren't actually antijoin rows, ie tmp_san_1.text *did* have a match in tmp_san_2, but that row chanced to have a null value of id. Possibly the planner could be smarter about estimating for this case, but it doesn't look much like a typical use-case to me. regards, tom lane -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance